/* ======================================================================
*   Copyright (C) 2022 Texas Instruments Incorporated
*
*   All rights reserved. Property of Texas Instruments Incorporated.
*   Restricted rights to use, duplicate or disclose this code are
*   granted through contract.
*
*   The program may not be used without the written permission
*   of Texas Instruments Incorporated or against the terms and conditions
*   stipulated in the agreement under which this program has been
*   supplied.
* ==================================================================== */

/**
 *  \file     Can_Priv.h
 *
 *  \brief    This file contains cover page for generating doxygen
 *            API documentation.
 */

/* Protection against multiple inclusion */
#ifndef CAN_PRIV_H_
#define CAN_PRIV_H_

#ifdef __cplusplus
extern "C"
{
#endif

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include "Can.h"
#include "CanIf_Cbk.h"

#include "Std_Types.h"

/*  Other Header Files */
#include "Can.h"
#if (CAN_DEV_ERROR_DETECT == STD_ON)
#include "Det.h"
#endif
#include "mcan.h"

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */
#define CAN_FD_PAYLOAD_MAX_BYTES (64U)

#define CAN_MAX_CONTROLLER_SUPPORTED       (4U)
/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */
/**
 * \brief Can Controller Type
 */
typedef enum
{
    CAN_CONTROLLER_TYPE_INFO_DCAN = 0x0U,
    /*!< DCAN Controller: CAN2.0A/B */
    CAN_CONTROLLER_TYPE_INFO_MCAN = 0x1U
    /*!< MCAN Controller: CAN FD */
} Can_ControllerTypeInfo;

/**
 * \brief Can FD controller Message RAM Configuration object structure.
 *        This structure will only be used in CAN FD controller i.e. MCAN
 */
typedef struct Can_FdMsgRAMConfigObjType_s
{
    MCAN_MsgRAMConfigParams     configParams;
    /*!< MCAN Message RAM Configuration parameters */
    MCAN_StdMsgIDFilterElement stdMsgIDFilterList[KMAX_MB_PER_CONTROLLER];
    /*!< Standard ID filter elements */
    MCAN_ExtMsgIDFilterElement extMsgIDFilterList[KMAX_MB_PER_CONTROLLER];
    /*!< Extended ID filter elements */
    uint8                 stdFilterNum;
    /*!< Standard ID filter element number */
    uint8                 extFilterNum;
    /*!< Extended ID filter element number */
    uint32                txMbMapping[2U][KMAX_MB_PER_CONTROLLER];
    /*!< Mapping of HTRH
     *   txMbMapping[0U][0-KMAX_MB_PER_CONTROLLER]: HTH to be stored into Buffer
     *   txMbMapping[1U][0-KMAX_MB_PER_CONTROLLER]: HTH to be stored into FIFO
     *   txMbMapping[m][n] = 0xFF : Initialization value */
    uint32                rxMbMapping[2U][KMAX_MB_PER_CONTROLLER];
    /*!< Mapping of HTRH
     *   rxMbMapping[0U][0-KMAX_MB_PER_CONTROLLER]: HRH is stored into Buffer
     *   rxMbMapping[1U][0-KMAX_MB_PER_CONTROLLER]: HRH is stored into FIFO
     *   rxMbMapping[m][n] = 0xFF : Initialization value */
    uint32                hthToMbMapping[KMAX_MB_PER_CONTROLLER];
    /*!< Mapping of og HTH to hw mailboxes */
    uint16                txBuffNum;
    /*!< Tx number of Buffer elements */
    uint16                txFIFONum;
    /*!< Tx number of FIFO elements */
    uint16                rxBuffNum;
    /*!< Rx number of Buffer elements */
    uint16                rxFIFONum;
    /*!< Rx number of FIFO elements */
} Can_FdMsgRAMConfigObjType;

/**
 * \brief Can controller object strucuture.
 */
typedef struct Can_ControllerObjType_s
{
    boolean               canBusOffRecoveryStatus;
    /*!< Bus off recovery status */
    uint8                 canTxStatus[KMAX_MB_PER_CONTROLLER];
    /*!< TxRXx Status of Mailbox */
    uint8                 canInterruptCounter;
    /*!< Total number of interrupts for this controller */
    uint16                canBaud;
    /*!< Set BRP value */
    uint8                 canSduPtr[CAN_FD_PAYLOAD_MAX_BYTES];
    /*!< SDU pointer */
    Can_ControllerType    canControllerConfig;
    /**< Can Controller */
    uint32                MaxBaudConfigID;
    /**< Max Baud Config Index in BaudRateConfigList */
    Can_ControllerStateType   canState;
    /**< State of Can */
    Can_HwType            mailboxCfg;
    /**< Structure which includes HOH, CAN Controller ID and specific CanId */
    PduInfoType           pduInfo;
    /**< Structure which includes pointer to the SDU and it's length */
    Can_FdMsgRAMConfigObjType   canFDMsgRamConfig;
    /*!< MCAN Message RAM configuration parameters */
} Can_ControllerObjType;

/**
 * \brief Can HWObject to Mailbox mapping type
 */
typedef uint32 Can_MbHTRHMapping_Type;

/**
 * \brief Can Mailbox type strucuture.
 */
typedef struct Can_MailboxObjType_s
{
    Can_MailboxType    mailBoxConfig;
    /**< Mailbox Config Info */
    PduIdType          canTxRxPduId[KMAX_MB_PER_CONTROLLER];
    /**< Tx/Rx Pdu ID Info */
} Can_MailboxObjType;

/**
 * \brief Can Driver object type strucuture.
 */
typedef struct Can_DriverObjType_s
{
    Can_ControllerObjType canController[KMAX_CONTROLLER];
    /**< List of enabled Controllers */
    Can_MailboxObjType    canMailbox[KMAX_MAILBOXES];
    /**< MB array for all controllers */
    uint8                 canMaxControllerCount;
    /**< MaxCount of Controller in Controller List */
    uint32                maxMbCnt;
    /**< MaxMbCount in MB list in all controller */
    uint32                controllerIDMap[CAN_MAX_CONTROLLER_SUPPORTED];
    /**< CAN Controller ID mapping */
} Can_DriverObjType;

/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */

FUNC(void, CAN_CODE) Can_hwUnitConfig(Can_ControllerObjType *canController,
                                      const Can_MailboxObjType *canMailbox,
                                      uint32 MaxMbCnt);

boolean Can_hwUnitStart(Can_ControllerObjType *controllerObj);

boolean Can_hwUnitStop(Can_ControllerObjType *controllerObj);

boolean Can_hwUnitSleep(Can_ControllerObjType *controllerObj);
boolean Can_mcanWkUp(Can_ControllerObjType * controllerObj);

Can_ReturnType Can_writeGetFreeMsgObj(const Can_MailboxType *mailboxCfg,
                                     const Can_ControllerObjType *controllerObj,
                                     uint32 *msgObj,
                                     uint32 htrh);

void Can_writeTxMailbox(const Can_MailboxType *mailboxCfg,
                        Can_ControllerObjType *controllerObj,
                        uint32 Hth,
                        uint32 messageBox,
                        const Can_PduType *PduInfo);

void Can_hwUnitDisableInterrupts(Can_ControllerObjType *controllerObj);

void Can_hwUnitEnableInterrupts(Can_ControllerObjType *controllerObj);

#if (CAN_CFG_DEINIT_API == STD_ON)
void Can_hwDeInit(const Can_ControllerObjType *canController);
#endif

void Can_hwUnitTxDonePolling(Can_ControllerObjType *canController,
                             const Can_MailboxObjType *canMailbox,
                             uint8 htrh);

Can_ReturnType Can_hwUnitCheckWakeup(uint32 baseAddr);

void Can_hwUnitChangeBaudrate(uint32 baseAddr,
                              uint32 brp);

void Can_hwUnitSetBaudrate(uint32 baseAddr,
                           const Can_BaudConfigType *setBaud);

#if  (CAN_WAKEUP_POLLING == STD_ON)
void Can_MainFunction_WakeupProcess(Can_ControllerObjType *canController);
#endif

void Can_MainFunction_BusOffProcess(Can_ControllerObjType *canController);

void Can_MainFunction_ModeProcess(Can_ControllerObjType *canController);

#if (CAN_RX_POLLING == STD_ON)
void Can_MainFunction_ReadProcess(Can_DriverObjType *can_DriverObj);
#endif

Std_ReturnType Can_hwUnitTestLoopBackModeEnable(uint32 baseAddr,
                                                uint8 mode);

Std_ReturnType Can_hwUnitTestLoopBackModeDisable(uint32 baseAddr,
                                                 uint8 mode);
#if defined(CAN_CONTROLLER_DCAN1)
#if (STD_ON == CAN_SAFETI_API)
Std_ReturnType Can_hwUnitRegReadBack(uint32 baseAddr, uint32 controllerType,
                                     Can_RegisterReadbackType *Can_CanConfig);
#endif

/* DCAN related functions */
void Can_dcanMessageRamInit(uint32 controllerCnt);

void Can_dcanConfigController(Can_ControllerObjType *canController,
                              const Can_MailboxObjType *canMailbox,
                              uint32 maxMbCnt);

boolean Can_dcanStart(Can_ControllerObjType * controllerObj);

boolean Can_dcanStop(Can_ControllerObjType * controllerObj);

boolean Can_dcanSleep(Can_ControllerObjType * controllerObj);


Can_ReturnType Can_dcanWriteGetFreeMsgObj(const Can_MailboxType *mailboxCfg,
                                          uint32         *msgObj,
                                          const uint8          *canTxStatus,
                                          uint32         baseAddr);

void Can_dcanWriteTxMailbox(uint32   baseAddr,
                            uint32   messageBox,
                            const Can_MailboxType *mailboxCfg,
                            const Can_PduType *PduInfo);

void Can_dcanDisableInterrupts(Can_ControllerObjType *controllerObj);

void Can_dcanEnableInterrupts(Can_ControllerObjType *controllerObj);

#if (CAN_CFG_DEINIT_API == STD_ON)
void Can_dcanHwDeInit(const Can_ControllerObjType *canController);
#endif

void Can_dcanTxDonePolling(Can_ControllerObjType *canController,
                           const Can_MailboxObjType *canMailbox);

Can_ReturnType Can_dcanCheckWakeup(uint32 baseAddr);

void Can_dcanChangeBaudrate(uint32 baseAddr, uint32 brp);

void Can_dcanSetBaudrate(uint32 baseAddr, const Can_BaudConfigType *setBaud);

#if  (CAN_WAKEUP_POLLING == STD_ON)
void Can_dcan_WakeupProcess(Can_ControllerObjType *canController);
#endif

void Can_dcan_BusOffProcess(Can_ControllerObjType *canController);

void Can_dcan_ModeProcess(Can_ControllerObjType *canController);

#if (CAN_RX_POLLING == STD_ON)
void Can_dcan_ReadProcess(uint32 baseAddr,
                          Can_ControllerObjType *controllerObj,
                          const Can_MailboxType *mailboxCfg);
#endif

Std_ReturnType Can_dcanTestLoopBackModeEnable(uint32 baseAddr, uint8 mode);

Std_ReturnType Can_dcanTestLoopBackModeDisable(uint32 baseAddr, uint8 mode);

void Can_dcanRxProcess(const Can_MailboxType *mailboxCfg,
                       const Can_ControllerType *controllerCfg,
                       Can_ControllerObjType *controllerObj,
                       uint16 msgObj);

void Can_dcanProcessISR(uint8 intType,
                        Can_ControllerObjType *canController,
                        const Can_MailboxObjType *canMailbox);

void Can_dcanProcessISRError(Can_ControllerObjType *canController);

void Can_dcanProcessISRTxRx(Can_ControllerObjType *canController,
                            const Can_MailboxObjType *canMailbox,
                            uint32 msgObj);

#if (STD_ON == CAN_SAFETI_API)
Std_ReturnType Can_dcanRegReadBack(uint32 baseAddr,
                                   Can_RegisterReadbackType *Can_CanConfig);
#endif

#if (STD_ON == CAN_ECC_ENABLE)
void Can_hwUnitEccParityEnable(const Can_ControllerObjType *canController,
                               uint8 flag,
                               uint8 ramInitEnable);
uint8 Can_hwUnitEccDiagnosticGetErrMsgBoxNum(uint32 baseAddr);
void Can_hwUnitEccDiagnosticModeEnable(uint32 baseAddr, uint8 flag);
uint32 Can_hwUnitEccGetErrStatus(uint32 baseAddr);
void Can_hwUnitEccClrErrStatus(uint32 baseAddr);
uint32 Can_dcanEccGetErrStatus(uint32 baseAddr);
void Can_dcanEccClrErrStatus(uint32 baseAddr);
void Can_dcanEccParityEnable(uint32 baseAddr, uint8 controller, uint8 flag,
                             uint8 ramInitEnable);
uint8 Can_dcanEccDiagnosticGetErrMsgBoxNum(uint32 baseAddr);
void Can_dcanEccDiagnosticModeEnable(uint32 baseAddr, uint8 flag);
#endif
#endif

/* MCAN related functions */
void Can_mcanConfigController(Can_ControllerObjType *canController,
                              const Can_MailboxObjType *canMailbox,
                              uint32 maxMbCnt);

boolean Can_mcanStart(Can_ControllerObjType *controllerObj);

boolean Can_mcanStop(Can_ControllerObjType * controllerObj);

boolean Can_mcanSleep(Can_ControllerObjType * controllerObj);


Std_ReturnType Can_mcanTestLoopBackModeEnable(uint32 baseAddr, uint8 mode);

Std_ReturnType Can_mcanTestLoopBackModeDisable(uint32 baseAddr, uint8 mode);

Can_ReturnType Can_mcanWriteGetFreeMsgObj(const Can_MailboxType *mailboxCfg,
                                    const Can_ControllerObjType *canController,
                                    uint32 *msgObj,
                                    uint32 htrh);

void Can_mcanWriteTxMailbox(const Can_MailboxType *mailboxCfg,
                            Can_ControllerObjType *controllerObj,
                            uint32   messageBox,
                            const Can_PduType *pduInfo,
                            uint32   hth);

void Can_mcanChangeBaudrate(uint32 baseAddr, uint32 brp);

void Can_mcanSetBaudrate(uint32 baseAddr, const Can_BaudConfigType *setBaud);

void Can_mcanDisableInterrupts(Can_ControllerObjType *controllerObj);

void Can_mcanEnableInterrupts(Can_ControllerObjType *canController);

Can_ReturnType Can_mcanCheckWakeup(uint32 baseAddr);

void Can_mcanTxDonePolling(Can_ControllerObjType *canController,
                           const Can_MailboxObjType *canMailbox,
                           uint8 htrh);

#if  (CAN_WAKEUP_POLLING == STD_ON)
void Can_mcan_WakeupProcess(Can_ControllerObjType *canController);
#endif

void Can_mcan_BusOffProcess(Can_ControllerObjType *canController);

void Can_mcan_ModeProcess(Can_ControllerObjType *canController);

#if (CAN_RX_POLLING == STD_ON)
void Can_mcan_ReadProcess(Can_ControllerObjType *controllerObj,
                          const Can_MailboxObjType *canMailbox,
                          uint32 maxMbCnt);
#endif

void Can_mcanReadRxBuff(Can_ControllerObjType *controllerObj,
                        const Can_MailboxObjType *canMailbox,
                        const Can_FdMsgRAMConfigObjType *ramConfig,
                        uint32 maxMbCnt);

void Can_mcanReadRxFIFO(Can_ControllerObjType *controllerObj,
                        const Can_MailboxObjType *canMailbox,
                        uint32 maxMbCnt);

void Can_mcanProcessISR(Can_ControllerObjType *canController,
                        const Can_MailboxObjType *canMailbox,
                        uint32 maxMbCnt);

#if (STD_ON == CAN_ECC_ENABLE)
void Can_mcanProcessECCISR(const Can_ControllerObjType *controllerObj);
#endif

void Can_mcanProcessISRTx(Can_ControllerObjType *canController,
                          const Can_MailboxObjType *canMailbox);

void Can_mcanProcessISRRx(Can_ControllerObjType *controllerObj,
                          const Can_MailboxObjType *canMailbox,
                          uint32 maxMbCnt);

#if (CAN_CFG_DEINIT_API == STD_ON)
void Can_mcanHwDeInit(const Can_ControllerObjType *canController);
#endif

Can_ErrorStateType Can_mcanGetProtocolStatus(const Can_ControllerObjType 
                                                                *canController);

#ifdef __cplusplus
}
#endif

#endif /* CAN_PRIV_ */

/*  End of File: Can_Priv.h */
