/*!
* @file     Can.h
*
* @version  1.0.0
*
* @brief    AUTOSAR CAN Driver header file
 *           
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_15-Nov-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifndef CAN_H
#define CAN_H

#ifdef __cplusplus
extern "C"{
#endif

#include "ComStack_Types.h"
#include "Can_Hw.h"
#include "Can_Cfg.h"
#include "Can_GeneralTypes.h"
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup CAN_Driver
  * @brief CAN driver modules
  @{
*/

/** @defgroup CAN_Macros
  @{
*/
/*******************************************************************************
                    VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define CAN_H_VENDOR_ID                     0x00C1U
/** Module ID of this module, as defined in the BSW Module List. */
#define CAN_H_MODULE_ID                     0x0050U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_H_AR_RELEASE_MAJOR_VERSION      0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_H_AR_RELEASE_MINOR_VERSION      0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CAN_H_AR_RELEASE_REVISION_VERSION   0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_H_SW_MAJOR_VERSION              0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_H_SW_MINOR_VERSION              0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CAN_H_SW_PATCH_VERSION              0x00U

/*******************************************************************************
                                VERSION CHECK
*******************************************************************************/
/* Make sure the vendor id is the same between Can.h and Can_Cfg.h */
#if (CAN_H_VENDOR_ID != CAN_CFG_H_VENDOR_ID)
    #error "Vendor id mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the module id is the same between Can.h and Can_Cfg.h */
#if (CAN_H_MODULE_ID != CAN_CFG_H_MODULE_ID)
    #error "Module id mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the AUTOSAR major version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_AR_RELEASE_MAJOR_VERSION != CAN_CFG_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR major version number mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_AR_RELEASE_MINOR_VERSION != CAN_CFG_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR minor version number mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_AR_RELEASE_REVISION_VERSION != CAN_CFG_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR revision version number mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the software major version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_SW_MAJOR_VERSION != CAN_CFG_H_SW_MAJOR_VERSION)
    #error "Software major version number mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the software minor version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_SW_MINOR_VERSION != CAN_CFG_H_SW_MINOR_VERSION)
    #error "Software minor version number mismatch between Can.h and Can_Cfg.h"
#endif
/* Make sure the software patch version number is the same between Can.h and Can_Cfg.h */
#if (CAN_H_SW_PATCH_VERSION != CAN_CFG_H_SW_PATCH_VERSION)
    #error "Software patch version number mismatch between Can.h and Can_Cfg.h"
#endif

#ifdef ENABLE_INTERMODULE_MCAL_CHECK
    /* Make sure the AUTOSAR major version number is the same between Can.h and ComStack_Types.h */
    #if (CAN_H_AR_RELEASE_MAJOR_VERSION != COM_STACK_TYPES_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR major version number mismatch between Can.h and ComStack_Types.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Can.h and ComStack_Types.h */
    #if (CAN_H_AR_RELEASE_MINOR_VERSION != COM_STACK_TYPES_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR minor version number mismatch between Can.h and ComStack_Types.h"
    #endif
#endif /* ENABLE_INTERMODULE_MCAL_CHECK */

/*******************************************************************************
                        AUTOSAR API SERVICE IDS
*******************************************************************************/
#define CAN_SID_INIT                            ((uint8)0x00U)
#define CAN_SID_MAIN_WRITE                      ((uint8)0x01U)
#define CAN_SID_SET_CONTROLLER_MODE             ((uint8)0x03U)
#define CAN_SID_DISABLE_CONTROLLER_INT          ((uint8)0x04U)
#define CAN_SID_ENABLE_CONTROLLER_INT           ((uint8)0x05U)
#define CAN_SID_WRITE                           ((uint8)0x06U)
#define CAN_SID_GET_VERSION_INFO                ((uint8)0x07U)
#define CAN_SID_MAIN_READ                       ((uint8)0x08U)
#define CAN_SID_MAIN_BUSOFF                     ((uint8)0x09U)
#define CAN_SID_MAIN_MODE                       ((uint8)0x0CU)
#define CAN_SID_SET_BAUDRATE                    ((uint8)0x0FU)
#define CAN_SID_DEINIT                          ((uint8)0x10U)
#define CAN_SID_GET_CONTROLLER_ERROR_STATE      ((uint8)0x11U)
#define CAN_SID_GET_CONTROLLER_MODE             ((uint8)0x12U)
#define CAN_SID_SET_CLOCK_MODE                  ((uint8)0x80U)
#define CAN_SID_ABORT_MB                        ((uint8)0x81U)
#define CAN_SID_SET_ICOM_CONFIG                 ((uint8)0x82U)
#define CAN_SID_MAIN_MULTI_WRITE                ((uint8)0x83U)

/*******************************************************************************
                            DET ERRORS
*******************************************************************************/
#define CAN_E_PARAM_POINTER         ((uint8)0x01U)
#define CAN_E_PARAM_HANDLE          ((uint8)0x02U)
#define CAN_E_PARAM_DATA_LENGTH     ((uint8)0x03U)
#define CAN_E_PARAM_CONTROLLER      ((uint8)0x04U)
#define CAN_E_UNINIT                ((uint8)0x05U)
#define CAN_E_TRANSITION            ((uint8)0x06U)
#define CAN_E_PARAM_BAUDRATE        ((uint8)0x07U)
#define CAN_E_ICOM_CONFIG_INVALID   ((uint8)0x08U)
#define CAN_E_INIT_FAILED           ((uint8)0x09U)
#define CAN_E_DATALOST              ((uint8)0x01U)
#define CAN_E_INVALID_CONTROLLER    ((uint8)0x80U)

/** Return value when the request could not be processed due to hardware busy */
#define CAN_BUSY  (0x02U)
/**@} end of group CAN_Macros */
/*******************************************************************************
                                ENUMS
*******************************************************************************/
/** @defgroup CAN_Enumerations
  @{
*/
/**
 * @brief   CAN ID type of a CAN hardware object
 */
typedef enum 
{
    CAN_EXTENDED = 0U,  //!< Extended CAN ID (29 bits) 
    CAN_STANDARD,       //!< Standard CAN ID (11 bits) 
    CAN_MIXED           //!< Mixed CAN ID (29 bits) 
} Can_IdCfgType;

#if (STD_ON == CAN_PUBLIC_ICOM_ENABLE)
/**
 * @brief   CAN Icom ID filtering type
 */
typedef enum
{
    EXACTLY = 0U,
    GREATER_MINNUM,
    SMALLER_MAXNUM,
    INSIDE_RANGE
} Can_IcomIdFilterType;
/**
 * @brief   CAN Icom payload filtering type
 */
typedef enum 
{
    AND = 0U,
    EQUAL,
    GREATER,
    SMALLER,
    XOR
} Can_IcomPayloadFilterType;
#endif

/**@} end of group CAN_Enumerations */
/*******************************************************************************
                            FUNCTION DECLARATIONS
*******************************************************************************/
/** @defgroup CAN_Fuctions
  @{
*/
#define CAN_START_SEC_CODE
#include "Can_MemMap.h"

extern FUNC(void, CAN_CODE) Can_Init(P2CONST(Can_ConfigType, AUTOMATIC, CAN_APPL_CONST) Config);

extern FUNC(void, CAN_CODE) Can_DeInit(void);

extern FUNC(Std_ReturnType, CAN_CODE) Can_SetControllerMode(
    VAR(uint8, AUTOMATIC) Controller,
    VAR(Can_ControllerStateType, AUTOMATIC) Transition);

extern FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerMode(
    VAR(uint8, AUTOMATIC) Controller,
    P2VAR(Can_ControllerStateType, AUTOMATIC, CAN_APPL_DATA) ControllerModePtr);

extern FUNC(Std_ReturnType, CAN_CODE) Can_Write(
    VAR(Can_HwHandleType, AUTOMATIC) Hth,
    P2CONST(Can_PduType, AUTOMATIC, CAN_APPL_CONST) PduInfo);

extern FUNC(void, CAN_CODE) Can_EnableControllerInterrupts(
    VAR(uint8, AUTOMATIC) Controller);

extern FUNC(void, CAN_CODE) Can_DisableControllerInterrupts(
    VAR(uint8, AUTOMATIC) Controller);

extern FUNC(Std_ReturnType, CAN_CODE) Can_GetControllerErrorState(
    VAR(uint8, AUTOMATIC) ControllerId,
    P2VAR(Can_ErrorStateType, AUTOMATIC, CAN_APPL_DATA) ErrorStatePtr);

#if (STD_ON == CAN_SET_BAUDRATE_API)
extern FUNC(Std_ReturnType, CAN_CODE) Can_SetBaudrate(
    VAR(uint8, AUTOMATIC) Controller,
    CONST(uint16, AUTOMATIC) BaudrateConfigId);
#endif /* STD_ON == CAN_SET_BAUDRATE_API */

#if (STD_ON == CAN_PUBLIC_ICOM_ENABLE)
extern FUNC(Std_ReturnType, CAN_CODE) Can_SetIcomConfiguration(
    VAR(uint8, AUTOMATIC) Controller,
    VAR(IcomConfigIdType, AUTOMATIC) ConfigurationId);
#endif /* STD_ON == CAN_PUBLIC_ICOM_ENABLE */

#if (STD_ON == CAN_GET_VERSION_INFO_API_ENABLE)
extern FUNC(void, CAN_CODE) Can_GetVersionInfo(
    P2VAR(Std_VersionInfoType, AUTOMATIC, CAN_APPL_DATA) VersionInfo);
#endif /* STD_ON == CAN_GET_VERSION_INFO_API_ENABLE */

#if (STD_ON == CAN_ABORT_MB_API_ENABLE)
extern FUNC(void, CAN_CODE) Can_AbortMb(VAR(Can_HwHandleType, AUTOMATIC) Hth);
#endif /* STD_ON == CAN_ABORT_MB_API_ENABLE */

extern FUNC(void, CAN_CODE) Can_MainFunction_Mode(void);

#if (STD_OFF == CAN_BUSOFF_INTERRUPT_HANDLE_ENABLE)
    extern FUNC(void, CAN_CODE) Can_MainFunction_BusOff(void);
#else
    #define Can_MainFunction_BusOff()
#endif /* STD_OFF == CAN_BUSOFF_INTERRUPT_HANDLE_ENABLE */

#if (STD_OFF == CAN_RX_INTERRUPT_HANDLE_ENABLE)
    extern FUNC(void, CAN_CODE) Can_MainFunction_Read(void);

    #ifdef CAN_MAINFUNCTION_MULTIPLE_READ
    #if (STD_ON == CAN_MAINFUNCTION_MULTIPLE_READ)

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_0
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_0(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_0 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_1
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_1(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_1 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_2
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_2(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_2 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_3
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_3(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_3 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_4
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_4(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_4 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_5
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_5(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_5 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_6
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_6(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_6 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_7
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_7(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_7 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_8
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_8(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_8 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_9
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_9(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_9 */

        #ifdef CAN_MAINFUNCTION_PERIOD_READ_10
        extern FUNC(void, CAN_CODE) Can_MainFunction_Read_10(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_READ_10 */

    #endif /* STD_ON == CAN_MAINFUNCTION_MULTIPLE_READ */
    #endif /* CAN_MAINFUNCTION_MULTIPLE_READ */

#else /* STD_ON == CAN_RX_INTERRUPT_HANDLE_ENABLE */
    #define Can_MainFunction_Read()
#endif /* STD_OFF == CAN_RX_INTERRUPT_HANDLE_ENABLE */

#if (STD_OFF == CAN_TX_INTERRUPT_HANDLE_ENABLE)
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write(void);

#ifdef CAN_MAINFUNCTION_MULTIPLE_WRITE
    #if (STD_ON == CAN_MAINFUNCTION_MULTIPLE_WRITE)

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_0
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_0(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_0 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_1
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_1(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_1 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_2
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_2(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_2 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_3
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_3(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_3 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_4
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_4(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_4 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_5
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_5(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_5 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_6
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_6(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_6 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_7
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_7(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_7 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_8
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_8(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_8 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_9
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_9(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_9 */

        #ifdef CAN_MAINFUNCTION_PERIOD_WRITE_10
        extern FUNC(void, CAN_CODE) Can_MainFunction_Write_10(void);
        #endif /* CAN_MAINFUNCTION_PERIOD_WRITE_10 */

    #endif /* STD_ON == CAN_MAINFUNCTION_MULTIPLE_WRITE */
#endif /* CAN_MAINFUNCTION_MULTIPLE_WRITE */

#else /* STD_ON == CAN_TX_INTERRUPT_HANDLE_ENABLE */
    #define Can_MainFunction_Write()
#endif /* STD_OFF == CAN_TX_INTERRUPT_HANDLE_ENABLE */

#define CAN_STOP_SEC_CODE
#include "Can_MemMap.h"
/**@} end of group CAN_Fuctions */
/*******************************************************************************
                                GLOBAL VARIABLES
*******************************************************************************/
/** @defgroup CAN_Variable
  @{
*/
#define CAN_START_SEC_CONFIG_DATA_UNSPECIFIED
#include "Can_MemMap.h"

/** CAN driver static configuration */
extern CONST(Can_StaticConfigType, CAN_CONST) g_canStaticConfig;

/** Post build CAN driver configuration */
CAN_CONF_PB

#define CAN_STOP_SEC_CONFIG_DATA_UNSPECIFIED
#include "Can_MemMap.h"

/**@} end of group CAN_Variable */
#ifdef __cplusplus
}
#endif

#endif /*CAN_H*/
/**@} end of group CAN_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
