/**
 *******************************************************************************
 * @file    dpm32m0xx_can.h
 *
 * @brief   This file contains all the functions prototypes for the CAN
 *          firmware library.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 *******************************************************************************/

#ifndef __DPM32M0XX_CAN_H__
#define __DPM32M0XX_CAN_H__


#ifdef __cplusplus
extern "C"
{
#endif

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif


#include "dpm32m0xx.h"

#if defined (DPM32M08x) && defined (DPM32M0CAN)

/**
 ******************************************************************************************************
 * @brief CAN time segment 1 time quantum enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_TSEG1_1TQ = 0x00UL,             /*!< 1 time quantum.  */
  CAN_TSEG1_2TQ,                      /*!< 2 time quantum.  */
  CAN_TSEG1_3TQ,                      /*!< 3 time quantum.  */
  CAN_TSEG1_4TQ,                      /*!< 4 time quantum.  */
  CAN_TSEG1_5TQ,                      /*!< 5 time quantum.  */
  CAN_TSEG1_6TQ,                      /*!< 6 time quantum.  */
  CAN_TSEG1_7TQ,                      /*!< 7 time quantum.  */
  CAN_TSEG1_8TQ,                      /*!< 8 time quantum.  */
  CAN_TSEG1_9TQ,                      /*!< 9 time quantum.  */
  CAN_TSEG1_10TQ,                     /*!< 10 time quantum. */
  CAN_TSEG1_11TQ,                     /*!< 11 time quantum. */
  CAN_TSEG1_12TQ,                     /*!< 12 time quantum. */
  CAN_TSEG1_13TQ,                     /*!< 13 time quantum. */
  CAN_TSEG1_14TQ,                     /*!< 14 time quantum. */
  CAN_TSEG1_15TQ,                     /*!< 15 time quantum. */
  CAN_TSEG1_16TQ                      /*!< 16 time quantum. */
} CAN_TSEG1Enum;


/**
 ******************************************************************************************************
 * @brief CAN time segment 2 time quantum enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_TSEG2_1TQ = 0x00UL,             /*!< 1 time quantum. */
  CAN_TSEG2_2TQ,                      /*!< 2 time quantum. */
  CAN_TSEG2_3TQ,                      /*!< 3 time quantum. */
  CAN_TSEG2_4TQ,                      /*!< 4 time quantum. */
  CAN_TSEG2_5TQ,                      /*!< 5 time quantum. */
  CAN_TSEG2_6TQ,                      /*!< 6 time quantum. */
  CAN_TSEG2_7TQ,                      /*!< 7 time quantum. */
  CAN_TSEG2_8TQ                       /*!< 8 time quantum. */
} CAN_TSEG2Enum;


/**
 ******************************************************************************************************
 * @brief CAN synchronization jump width time quantum enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_SJW_1TQ = 0x00UL,               /*!< 1 time quantum. */
  CAN_SJW_2TQ,                        /*!< 2 time quantum. */
  CAN_SJW_3TQ,                        /*!< 3 time quantum. */
  CAN_SJW_4TQ                         /*!< 4 time quantum. */
} CAN_SJWEnum;


/**
 ******************************************************************************************************
 * @brief CAN sampling multiple enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_SAM_SINGLE = 0x00UL,            /*!< triple sampling. */
  CAN_SAM_THREE                       /*!< single sampling. */
} CAN_SAMEnum;


/**
 ******************************************************************************************************
 * @brief CAN remote transmission request type enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_RTR_TYPE_DATA = 0x00UL,         /*!< Data frame.   */
  CAN_RTR_TYPE_REMOTE                 /*!< Remote frame. */
} CAN_RTRTypeEnum;

/**
 ******************************************************************************************************
 * @brief CAN basic functions interrupt type enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_INT_TYPE_RX            = CAN_BASE_CTRL_RIE_Msk,             /*!< Reception interrupt.       */
  CAN_INT_TYPE_TX            = CAN_BASE_CTRL_TIE_Msk,             /*!< Transmission interrupt.    */
  CAN_INT_TYPE_ERR           = CAN_BASE_CTRL_EIE_Msk,             /*!< Error interrupt.           */
  CAN_INT_TYPE_OVERRUN       = CAN_BASE_CTRL_OIE_Msk,             /*!< Over run interrupt.        */
  CAN_INT_TYPE_OVERRHAP      = CAN_BASE_CTRL_OVRRHIE_Msk          /*!< Over run happen interrupt. */
} CAN_IntTypeEnum;

/**
 ******************************************************************************************************
 * @brief CAN basic functions interrupt flag enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_INT_FLAG_RX             = CAN_BASE_INTERRUPT_RI_Msk,              /*!< Reception interrupt flag.       */
  CAN_INT_FLAG_TX             = CAN_BASE_INTERRUPT_TI_Msk,              /*!< Transmission interrupt flag.    */
  CAN_INT_FLAG_ERR            = CAN_BASE_INTERRUPT_EI_Msk,              /*!< Error interrupt flag.           */
  CAN_INT_FLAG_OVERRUN        = CAN_BASE_INTERRUPT_DOI_Msk,             /*!< Over run interrupt flag.        */
  CAN_INT_FLAG_OVERRHAP       = CAN_BASE_INTERRUPT_OVRROI_Msk           /*!< Over run happen interrupt flag. */
} CAN_IntFlagEnum;


/**
 ******************************************************************************************************
 * @brief CAN basic functions interrupt flag enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_FLAG_RBS                = CAN_BASE_STATUS_RBS_Msk,      /*!< Receive buffer status.        */
  CAN_FLAG_DOS                = CAN_BASE_STATUS_DOS_Msk,      /*!< Data over run status.         */
  CAN_FLAG_TBS                = CAN_BASE_STATUS_TBS_Msk,      /*!< Transmit buffer status.       */
  CAN_FLAG_TCS                = CAN_BASE_STATUS_TCS_Msk,      /*!< Transmission complete status. */
  CAN_FLAG_RS                 = CAN_BASE_STATUS_RS_Msk,       /*!< Receive status.               */
  CAN_FLAG_TS                 = CAN_BASE_STATUS_TS_Msk,       /*!< Transmit status.              */
  CAN_FLAG_ES                 = CAN_BASE_STATUS_ES_Msk,       /*!< Error status.                 */
  CAN_FLAG_BS                 = CAN_BASE_STATUS_BS_Msk,       /*!< Bus status.                   */
  CAN_FLAG_OHS                = CAN_BASE_STATUS_OVRROS_Msk    /*!< Over run happen status.       */
} CAN_FlagEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI listen only mode enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_LOM_DISABLE = 0x00UL,      /*!< Disable listen only mode. */
  CAN_PELI_LOM_ENABLE                 /*!< Enable listen only mode.  */
} CAN_PELI_LOMEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI self test mode enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_STM_DISABLE = 0x00UL,      /*!< Disable self test mode. */
  CAN_PELI_STM_ENABLE                 /*!< Enable self test mode.  */
} CAN_PELI_STMEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI acceptance filter mode enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_AFM_DUAL = 0x00UL,         /*!< Select two acceptance filters (16 bits active each). */
  CAN_PELI_AFM_SINGLE                 /*!< Single acceptance filter (32-bit length).            */
} CAN_PELI_AFMEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI frame format enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_IDE_STD = 0x00UL,        /*!< Standard frame format. */
  CAN_PELI_IDE_EXT                  /*!< Extended frame format. */
} CAN_PELI_IDEEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI frame type enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_RTR_DATA = 0x00UL,         /*!< Data Frame.   */
  CAN_PELI_RTR_REMOTE                 /*!< Remote frame. */
} CAN_PELI_RTREnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI error type enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_ERRTYPE_BIT = 0x00UL,      /*!< Bit error.           */
  CAN_PELI_ERRTYPE_FORMAT,            /*!< Format error.        */
  CAN_PELI_ERRTYPE_STUFF,             /*!< Stuff error.         */
  CAN_PELI_ERRTYPE_OTHER              /*!< Other type of error. */
} CAN_PELI_ErrTypeEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI error direction enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_ERRDIR_TRANSMITTER = 0x00UL,  /*!< Error while sending.   */
  CAN_PELI_ERRDIR_RECEIVER               /*!< Error while receiving. */
} CAN_PELI_ErrDirectionEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI error segment enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_ERRSEG_ID28_21 = 0x02UL,      /*!< ID.28 to ID.21.         */
  CAN_PELI_ERRSEG_START_FRAME,           /*!< Start of frame.         */
  CAN_PELI_ERRSEG_SRTR,                  /*!< Bit SRTR.               */
  CAN_PELI_ERRSEG_IDE,                   /*!< Bit IDE.                */
  CAN_PELI_ERRSEG_ID20_18,               /*!< ID.20 to ID.18.         */
  CAN_PELI_ERRSEG_ID17_13,               /*!< ID.17 to ID.13.         */
  CAN_PELI_ERRSEG_CRC,                   /*!< CRC sequence.           */
  CAN_PELI_ERRSEG_RESERVED_BIT0,         /*!< Reserved bit 0.         */
  CAN_PELI_ERRSEG_DATA,                  /*!< Data field.             */
  CAN_PELI_ERRSEG_DATA_LEN,              /*!< Data length code.       */
  CAN_PELI_ERRSEG_RTR,                   /*!< Bit RTR.                */
  CAN_PELI_ERRSEG_RESERVED_BIT1,         /*!< Reserved bit 1.         */
  CAN_PELI_ERRSEG_ID4_0,                 /*!< ID.4 to ID.0.           */
  CAN_PELI_ERRSEG_ID12_5,                /*!< ID.12 to ID.5.          */
  CAN_PELI_ERRSEG_ACTIVE_ERR,            /*!< Active error flag.      */
  CAN_PELI_ERRSEG_INTERMISSION,          /*!< Intermission.           */
  CAN_PELI_ERRSEG_TOLERATE,              /*!< Tolerate dominant bits. */
  CAN_PELI_ERRSEG_PASSIVE_ERR = 0x16UL,  /*!< Passive error flag.     */
  CAN_PELI_ERRSEG_ERR_DELIMITER,         /*!< Error delimiter.        */
  CAN_PELI_ERRSEG_CRC_DELIMITER,         /*!< CRC delimiter.          */
  CAN_PELI_ERRSEG_ACK_SLOT,              /*!< Acknowledge slot.       */
  CAN_PELI_ERRSEG_END_FRAME,             /*!< End of frame.           */
  CAN_PELI_ERRSEG_ACK_DELIMITER,         /*!< Acknowledge delimiter.  */
  CAN_PELI_ERRSEG_ACK_OVERLOAD,          /*!< Overload flag.          */
  CAN_PELI_ERRSEG_ACK_UNKNOWN            /*!< Unknown.                */
} CAN_PELI_ErrSegmentEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI interrupt type enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_INT_TYPE_OVERR_HAP        = CAN_PELI_IE_OVRRHIE_Msk,  /*!< Overrun happen interrupt enable.   */
  CAN_PELI_INT_TYPE_BUS_ERR          = CAN_PELI_IE_BEIE_Msk,     /*!< Bus error interrupt enable.        */
  CAN_PELI_INT_TYPE_ARB_LOST         = CAN_PELI_IE_ALIE_Msk,     /*!< Arbitration lost interrupt enable. */
  CAN_PELI_INT_TYPE_ERR_PASSIVE      = CAN_PELI_IE_EPIE_Msk,     /*!< Error passive interrupt enable.    */
  CAN_PELI_INT_TYPE_OVERR            = CAN_PELI_IE_DOIE_Msk,     /*!< Data overrun interrupt enable.     */
  CAN_PELI_INT_TYPE_ERR_WARRING      = CAN_PELI_IE_EIE_Msk,      /*!< Error warning interrupt enable.    */
  CAN_PELI_INT_TYPE_TX               = CAN_PELI_IE_TIE_Msk,      /*!< Transmit interrupt enable.         */
  CAN_PELI_INT_TYPE_RX               = CAN_PELI_IE_RIE_Msk       /*!< Receive interrupt enable.          */
} CAN_PELI_IntTypeEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI interrupt flag enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_INT_FLAG_OVERR_HAP   = CAN_PELI_INTERRUPT_OVRROI_Msk,   /*!< Overrun happen interrupt falg.     */
  CAN_PELI_INT_FLAG_BUS_ERR     = CAN_PELI_INTERRUPT_BEI_Msk,      /*!< Bus error interrupt falg.          */
  CAN_PELI_INT_FLAG_ARB_LOST    = CAN_PELI_INTERRUPT_ALI_Msk,      /*!< Arbitration lost interrupt falg.   */
  CAN_PELI_INT_FLAG_ERR_PASSIVE = CAN_PELI_INTERRUPT_EPI_Msk,      /*!< Error passive interrupt falg.      */
  CAN_PELI_INT_FLAG_OVERR       = CAN_PELI_INTERRUPT_DOI_Msk,      /*!< Data Overrun interrupt falg.       */
  CAN_PELI_INT_FLAG_ERR_WARRING = CAN_PELI_INTERRUPT_EI_Msk,       /*!< Error warning interrupt falg.      */
  CAN_PELI_INT_FLAG_TX          = CAN_PELI_INTERRUPT_TI_Msk,       /*!< Transmit interrupt falg.           */
  CAN_PELI_INT_FLAG_RX          = CAN_PELI_INTERRUPT_RI_Msk        /*!< Receive interrupt falg.            */
} CAN_PELI_IntFlagEnum;

/**
 ******************************************************************************************************
 * @brief CAN_PELI flag enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_FLAG_OHS           = CAN_PELI_STATUS_OVRROS_Msk,   /*!< Overrun happen status.             */
  CAN_PELI_FLAG_BS            = CAN_PELI_STATUS_BS_Msk,       /*!< Bus status.                        */
  CAN_PELI_FLAG_ES            = CAN_PELI_STATUS_ES_Msk,       /*!< Error status.                      */
  CAN_PELI_FLAG_TS            = CAN_PELI_STATUS_TS_Msk,       /*!< Transmit status.                   */
  CAN_PELI_FLAG_RS            = CAN_PELI_STATUS_RS_Msk,       /*!< Receive status.                    */
  CAN_PELI_FLAG_TCS           = CAN_PELI_STATUS_TCS_Msk,      /*!< Transmission complete status.      */
  CAN_PELI_FLAG_TBS           = CAN_PELI_STATUS_TBS_Msk,      /*!< Transmit buffer status.            */
  CAN_PELI_FLAG_DOS           = CAN_PELI_STATUS_DOS_Msk,      /*!< Data overrun status.               */
  CAN_PELI_FLAG_RBS           = CAN_PELI_STATUS_RBS_Msk       /*!< Receive buffer status.             */
} CAN_PELI_FlagEnum;


/**
 ******************************************************************************************************
 * @brief CAN_PELI arbitration lost bit enumeration.
 *****************************************************************************************************/
typedef enum
{
  CAN_PELI_ARBLOST_BIT_1 = 0x00UL,  /*!< Arbitration lost in bit 1 of identifier.  */
  CAN_PELI_ARBLOST_BIT_2,           /*!< Arbitration lost in bit 2 of identifier.  */
  CAN_PELI_ARBLOST_BIT_3,           /*!< Arbitration lost in bit 3 of identifier.  */
  CAN_PELI_ARBLOST_BIT_4,           /*!< Arbitration lost in bit 4 of identifier.  */
  CAN_PELI_ARBLOST_BIT_5,           /*!< Arbitration lost in bit 5 of identifier.  */
  CAN_PELI_ARBLOST_BIT_6,           /*!< Arbitration lost in bit 6 of identifier.  */
  CAN_PELI_ARBLOST_BIT_7,           /*!< Arbitration lost in bit 7 of identifier.  */
  CAN_PELI_ARBLOST_BIT_8,           /*!< Arbitration lost in bit 8 of identifier.  */
  CAN_PELI_ARBLOST_BIT_9,           /*!< Arbitration lost in bit 9 of identifier.  */
  CAN_PELI_ARBLOST_BIT_10,          /*!< Arbitration lost in bit 10 of identifier. */
  CAN_PELI_ARBLOST_BIT_11,          /*!< Arbitration lost in bit 11 of identifier. */
  CAN_PELI_ARBLOST_BIT_SRTR,        /*!< Arbitration lost in bit SRTR.             */
  CAN_PELI_ARBLOST_BIT_IDE,         /*!< Arbitration lost in bit IDE.              */
  CAN_PELI_ARBLOST_BIT_12,          /*!< Arbitration lost in bit 12 of identifier. */
  CAN_PELI_ARBLOST_BIT_13,          /*!< Arbitration lost in bit 13 of identifier. */
  CAN_PELI_ARBLOST_BIT_14,          /*!< Arbitration lost in bit 14 of identifier. */
  CAN_PELI_ARBLOST_BIT_15,          /*!< Arbitration lost in bit 15 of identifier. */
  CAN_PELI_ARBLOST_BIT_16,          /*!< Arbitration lost in bit 16 of identifier. */
  CAN_PELI_ARBLOST_BIT_17,          /*!< Arbitration lost in bit 17 of identifier. */
  CAN_PELI_ARBLOST_BIT_18,          /*!< Arbitration lost in bit 18 of identifier. */
  CAN_PELI_ARBLOST_BIT_19,          /*!< Arbitration lost in bit 19 of identifier. */
  CAN_PELI_ARBLOST_BIT_20,          /*!< Arbitration lost in bit 20 of identifier. */
  CAN_PELI_ARBLOST_BIT_21,          /*!< Arbitration lost in bit 21 of identifier. */
  CAN_PELI_ARBLOST_BIT_22,          /*!< Arbitration lost in bit 22 of identifier. */
  CAN_PELI_ARBLOST_BIT_23,          /*!< Arbitration lost in bit 23 of identifier. */
  CAN_PELI_ARBLOST_BIT_24,          /*!< Arbitration lost in bit 24 of identifier. */
  CAN_PELI_ARBLOST_BIT_25,          /*!< Arbitration lost in bit 25 of identifier. */
  CAN_PELI_ARBLOST_BIT_26,          /*!< Arbitration lost in bit 26 of identifier. */
  CAN_PELI_ARBLOST_BIT_27,          /*!< Arbitration lost in bit 27 of identifier. */
  CAN_PELI_ARBLOST_BIT_28,          /*!< Arbitration lost in bit 28 of identifier. */
  CAN_PELI_ARBLOST_BIT_29,          /*!< Arbitration lost in bit 19 of identifier. */
  CAN_PELI_ARBLOST_BIT_RTR          /*!< Arbitration lost in bit RTR.              */
} CAN_PELI_ARBLostBitEnum;



/**
 ******************************************************************************************************
 * @brief CAN_Basic initialization structure definition.
 *****************************************************************************************************/
typedef struct
{
  uint8_t CAN_Prescaler;                /*!< Specifies the baud rate prescaler value.
                                                   This parameter can be a number between 0x00 and 0xFF.
                                                   @note T(scl) = 2 × (BRP+1) x T(clk).                    */

  uint8_t CAN_SyncJumpWidth;            /*!< Specifies the time quantum of the synchronization jump width.
                                                   This parameter can be a value of @ref CAN_SJWEnum       */

  uint8_t CAN_Sampling;                 /*!< Specifies the sampling multiple.
                                                   This parameter can be a value of @ref CAN_SAMEnum       */

  uint8_t CAN_TimeSegment1;             /*!< Specifies the time quantum for time segment 1.
                                                   This parameter can be a value of @ref CAN_TSEG1Enum     */

  uint8_t CAN_TimeSegment2;             /*!< Specifies the time quantum for time segment 2.
                                                   This parameter can be a value of @ref CAN_TSEG2Enum     */
} CAN_InitTypeStruct;

/**
 ******************************************************************************************************
 * @brief CAN_Basic filter initialization structure definition.
 *****************************************************************************************************/
typedef struct
{
  uint8_t CAN_FilterId;         /*!< Specifies the filter identification number .
                                           This parameter can be a value between 0x00 and 0xFF */

  uint8_t CAN_FilterMaskId;     /*!< Specifies the filter mask number or identification number,
                                           This parameter can be a value between 0x00 and 0xFF */

} CAN_FilterInitTypeStruct;

/**
 ******************************************************************************************************
 * @brief CAN_Basic message structure definition.
 *****************************************************************************************************/
typedef struct
{
  uint16_t ID;                    /*!< Specifies the standard identifier.
                                       This parameter can be a value between 0 to 0x7FF. */

  uint8_t RTR;                    /*!< Specifies the type of frame for the received message.
                                       This parameter can be @ref CAN_RTRTypeEnum */

  uint8_t DLC;                    /*!< Specifies the length of the frame that will be received.
                                       This parameter can be a value between 0 to 8 */

  uint8_t Data[8];                /*!< Contains the data to be received. It ranges from 0 to 0xFF. */
} CanBasicMsg;


/**
 ******************************************************************************************************
 * @brief CAN_PELI initialization structure definition.
 *****************************************************************************************************/
typedef struct
{
  uint32_t CAN_PELI_Prescaler;              /*!< Specifies the baud rate prescaler value.
                                                 This parameter can be a number between 0x00 and 0xFF.
                                                 @note T(scl) = 2 × (BRP+1) x T(clk).                          */

  uint32_t CAN_PELI_SyncJumpWidth;          /*!< Specifies the time quantum of the synchronization jump width.
                                                 This parameter can be a value of @ref CAN_SJWEnum             */

  uint32_t CAN_PELI_Sampling;               /*!< Specifies the sampling multiple.
                                                 This parameter can be a value of @ref CAN_SAMEnum             */

  uint32_t CAN_PELI_TimeSegment1;           /*!< Specifies the time quantum for time segment 1.
                                                 This parameter can be a value of @ref CAN_TSEG1Enum           */

  uint32_t CAN_PELI_TimeSegment2;           /*!< Specifies the time quantum for time segment 2.
                                                 This parameter can be a value of @ref CAN_TSEG2Enum           */

  uint32_t CAN_PELI_ListenOnlyMode;         /*!< Specifies if listen only mode is selected.
                                                 This parameter can be a value of @ref CAN_PELI_LOMEnum        */

  uint32_t CAN_PELI_SelfTestMode;           /*!< Specifies if self test mode is selected.
                                                 This parameter can be a value of @ref CAN_PELI_STMEnum        */

  uint32_t CAN_PELI_ErrorWarningLimit;      /*!< Specifies error limit alarm thresholds.
                                                 This parameter can be a number between 0x00 and 0xFF.         */

} CAN_PELI_InitTypeStruct;



/**
 ******************************************************************************************************
 * @brief CAN_PELI filter init structure definition
 *****************************************************************************************************/
typedef struct
{
  uint8_t CAN_PELI_AcceptanceFilterMode;    /*!< Specifies acceptance filter mode.
                                                 This parameter can be a value of @ref CAN_PELI_AFMEnum     */

  uint8_t CAN_PELI_FilterId0;               /*!< Specifies the filter identification number.
                                                 This parameter can be a value between 0x00 and 0xFF        */
  uint8_t CAN_PELI_FilterId1;
  uint8_t CAN_PELI_FilterId2;
  uint8_t CAN_PELI_FilterId3;

  uint8_t CAN_PELI_FilterMaskId0;           /*!< Specifies the filter mask number or identification number.
                                                 This parameter can be a value between 0x00 and 0xFF        */
  uint8_t CAN_PELI_FilterMaskId1;
  uint8_t CAN_PELI_FilterMaskId2;
  uint8_t CAN_PELI_FilterMaskId3;

} CAN_PELI_FilterInitTypeStruct;


/**
 ******************************************************************************************************
 * @brief CAN_Peli_Tx/CAN_Peli_Rx message structure definition
 *****************************************************************************************************/
typedef struct
{
  uint32_t ID;       /*!< Specifies a standard frame format or extended frame format identifier.
                          Standard frame format can be a value between 0 and 0x7FF
                          The extended frame format can be a value between 0 and 0x1FFFFFFF          */

  uint8_t IDE;       /*!< Specifies the type of identifier for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_PELI_IDEEnum                     */

  uint8_t RTR;       /*!< Specifies the type of frame for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_PELI_RTREnum                     */

  uint8_t DLC;       /*!< Specifies the length of the frame that will be transmitted.
                          This parameter can be a value between 0 to 8                               */

  uint8_t Data[8];   /*!< Contains the data to be transmitted.
                          It ranges from 0 to 0xFF.                                                  */
} CanPeliMsg;


/* CAN Param Check. */
#define IS_CAN_SJW(x)                     (((x) == CAN_SJW_1TQ) || \
    ((x) == CAN_SJW_2TQ) || \
    ((x) == CAN_SJW_3TQ) || \
    ((x) == CAN_SJW_4TQ))

#define IS_CAN_SAMPLING(x)                (((x) == CAN_SAM_SINGLE) || \
    ((x) == CAN_SAM_THREE))

#define IS_CAN_TSEG1(x)                   (((x) == CAN_TSEG1_1TQ) || \
    ((x) == CAN_TSEG1_2TQ) || \
    ((x) == CAN_TSEG1_3TQ) || \
    ((x) == CAN_TSEG1_4TQ) || \
    ((x) == CAN_TSEG1_5TQ) || \
    ((x) == CAN_TSEG1_6TQ) || \
    ((x) == CAN_TSEG1_7TQ) || \
    ((x) == CAN_TSEG1_8TQ) || \
    ((x) == CAN_TSEG1_9TQ) || \
    ((x) == CAN_TSEG1_10TQ) || \
    ((x) == CAN_TSEG1_11TQ) || \
    ((x) == CAN_TSEG1_12TQ) || \
    ((x) == CAN_TSEG1_13TQ) || \
    ((x) == CAN_TSEG1_14TQ) || \
    ((x) == CAN_TSEG1_15TQ) || \
    ((x) == CAN_TSEG1_16TQ))

#define IS_CAN_TSEG2(x)                   (((x) == CAN_TSEG2_1TQ) || \
    ((x) == CAN_TSEG2_2TQ) || \
    ((x) == CAN_TSEG2_3TQ) || \
    ((x) == CAN_TSEG2_4TQ) || \
    ((x) == CAN_TSEG2_5TQ) || \
    ((x) == CAN_TSEG2_6TQ) || \
    ((x) == CAN_TSEG2_7TQ) || \
    ((x) == CAN_TSEG2_8TQ))

#define IS_CAN_INT_TYPE(x)                (((x & CAN_INT_TYPE_RX) == CAN_INT_TYPE_RX) || \
    ((x & CAN_INT_TYPE_TX) == CAN_INT_TYPE_TX) || \
    ((x & CAN_INT_TYPE_ERR) == CAN_INT_TYPE_ERR) || \
    ((x & CAN_INT_TYPE_OVERRUN) == CAN_INT_TYPE_OVERRUN) || \
    ((x & CAN_INT_TYPE_OVERRHAP) == CAN_INT_TYPE_OVERRHAP))

#define IS_CAN_INT_FLAG(x)                (((x) == CAN_INT_FLAG_RX) || \
    ((x) == CAN_INT_FLAG_TX) || \
    ((x) == CAN_INT_FLAG_ERR) || \
    ((x) == CAN_INT_FLAG_OVERRUN) || \
    ((x) == CAN_INT_FLAG_OVERRHAP))

#define IS_CAN_RTR_TYPE(x)                (((x) == CAN_RTR_TYPE_DATA) || \
    ((x) == CAN_RTR_TYPE_REMOTE))

#define IS_CAN_DLC(x)                     ((x) <= 8)

#define IS_CAN_FLAG(x)                    (((x) == CAN_FLAG_RBS) || \
    ((x) == CAN_FLAG_DOS) || \
    ((x) == CAN_FLAG_TBS) || \
    ((x) == CAN_FLAG_TCS) || \
    ((x) == CAN_FLAG_RS) || \
    ((x) == CAN_FLAG_TS) || \
    ((x) == CAN_FLAG_ES) || \
    ((x) == CAN_FLAG_BS) || \
    ((x) == CAN_FLAG_OHS))


/* CAN_PELI Param Check. */
#define IS_CAN_PELI_BRP_VAL(x)            (((x) <= 0xFF))

#define IS_CAN_PELI_SJW(x)                (IS_CAN_SJW(x))

#define IS_CAN_PELI_SAM(x)                (IS_CAN_SAMPLING(x))

#define IS_CAN_PELI_TSEG1(x)              (IS_CAN_TSEG1(x))

#define IS_CAN_PELI_TSEG2(x)              (IS_CAN_TSEG2(x))

#define IS_CAN_PELI_LOM(x)                (((x) == CAN_PELI_LOM_DISABLE) || \
    ((x) == CAN_PELI_LOM_ENABLE))

#define IS_CAN_PELI_STM(x)                (((x) == CAN_PELI_STM_DISABLE) || \
    ((x) == CAN_PELI_STM_ENABLE))

#define IS_CAN_PELI_EWL_VAL(x)            (((x) <= 0xFF))

#define IS_CAN_PELI_AFM(x)                (((x) == CAN_PELI_AFM_DUAL) || \
    ((x) == CAN_PELI_AFM_SINGLE))

#define IS_CAN_PELI_FILTER_ID_VAL(x)      (((x) <= 0xFF))

#define IS_CAN_PELI_FILTER_MASK_VAL(x)    (((x) <= 0xFF))

#define IS_CAN_PELI_STD_ID_VAL(x)         (((x) <= 0x7FF))

#define IS_CAN_PELI_EXD_ID_VAL(x)         (((x) <= 0x1FFFFFFF))

#define IS_CAN_PELI_IDE(x)                (((x) == CAN_PELI_IDE_STD) || \
    ((x) == CAN_PELI_IDE_EXT))

#define IS_CAN_PELI_RTR(x)                (((x) == CAN_PELI_RTR_DATA) || \
    ((x) == CAN_PELI_RTR_REMOTE))

#define IS_CAN_PELI_DLC_VAL(x)            (((x) <= 0x08))

#define IS_CAN_PELI_INT_TYPE(x)           (((x) == CAN_PELI_INT_TYPE_OVERR_HAP) || \
    ((x) == CAN_PELI_INT_TYPE_BUS_ERR) || \
    ((x) == CAN_PELI_INT_TYPE_ARB_LOST) || \
    ((x) == CAN_PELI_INT_TYPE_ERR_PASSIVE) || \
    ((x) == CAN_PELI_INT_TYPE_OVERR) || \
    ((x) == CAN_PELI_INT_TYPE_ERR_WARRING) || \
    ((x) == CAN_PELI_INT_TYPE_TX) || \
    ((x) == CAN_PELI_INT_TYPE_RX))

#define IS_CAN_PELI_INT_FLAG(x)           (((x) == CAN_PELI_INT_FLAG_OVERR_HAP) || \
    ((x) == CAN_PELI_INT_FLAG_BUS_ERR) || \
    ((x) == CAN_PELI_INT_FLAG_ARB_LOST) || \
    ((x) == CAN_PELI_INT_FLAG_ERR_PASSIVE) || \
    ((x) == CAN_PELI_INT_FLAG_OVERR) || \
    ((x) == CAN_PELI_INT_FLAG_ERR_WARRING) || \
    ((x) == CAN_PELI_INT_FLAG_TX) || \
    ((x) == CAN_PELI_INT_FLAG_RX))

#define IS_CAN_PELI_FLAG(x)               (((x) == CAN_PELI_FLAG_OHS) || \
    ((x) == CAN_PELI_FLAG_BS) || \
    ((x) == CAN_PELI_FLAG_ES) || \
    ((x) == CAN_PELI_FLAG_TS) || \
    ((x) == CAN_PELI_FLAG_RS) || \
    ((x) == CAN_PELI_FLAG_TCS) || \
    ((x) == CAN_PELI_FLAG_TBS) || \
    ((x) == CAN_PELI_FLAG_DOS) || \
    ((x) == CAN_PELI_FLAG_RBS))



/********************************************* Basic Work function *********************************************/
void                          CAN_ResetModeCmd(FunctionalState NewState);
void                          CAN_ClearDataOverflow(void);
void                          CAN_ClearIntPendingBit(void);

void                          CAN_DeInit(void);
void                          CAN_Init(CAN_InitTypeStruct* CAN_InitType);
void                          CAN_StructInit(CAN_InitTypeStruct* CAN_InitType);
void                          CAN_Cmd(FunctionalState Newstate);
void                          CAN_FilterInit(CAN_FilterInitTypeStruct* CAN_FilterInitStruct);
void                          CAN_FilterStructInit(CAN_FilterInitTypeStruct* CAN_FilterInitStruct);

void                          CAN_ReceiveFIFORelease(void);
void                          CAN_CancelTransmit(void);
void                          CAN_Transmit(CanBasicMsg* TxMessage);
void                          CAN_TransmitRepeat(CanBasicMsg* TxMessage);
void                          CAN_Receive(CanBasicMsg* RxMessage);

void                          CAN_IntCmd(uint32_t CAN_IntType, FunctionalState Newstate);
FunctionalState               CAN_GetIntCmdStatus(CAN_IntTypeEnum CAN_IntType);
FlagState                     CAN_GetIntFlagStatus(CAN_IntFlagEnum CAN_IntFlag);
FlagState                     CAN_GetFlagStatus(CAN_FlagEnum CAN_Flag);


/********************************************* Peli Work function *********************************************/
void                          CAN_PELI_ResetModeCmd(FunctionalState Newstate);
void                          CAN_PELI_ClearDataOverflow(void);
void                          CAN_PELI_ClearITPendingBit(void);

void                          CAN_PELI_DeInit(void);
void                          CAN_PELI_Init(CAN_PELI_InitTypeStruct* CAN_Peli_InitType);
void                          CAN_PELI_StructInit(CAN_PELI_InitTypeStruct* CAN_Peli_InitType);
void                          CAN_PELI_Cmd(FunctionalState Newstate);
void                          CAN_PELI_FilterInit(CAN_PELI_FilterInitTypeStruct* CAN_Peli_FilterInitType);
void                          CAN_PELI_FilterStructInit(CAN_PELI_FilterInitTypeStruct *CAN_Peli_FilterInitType);

void                          CAN_PELI_Transmit(CanPeliMsg* TxMessage);
void                          CAN_PELI_TransmitRepeat(CanPeliMsg* TxMessage);
void                          CAN_PELI_Receive(CanPeliMsg* RxMessage);
void                          CAN_PELI_CancelTransmit(void);
void                          CAN_PELI_ReceiveFIFORelease(void);

CAN_PELI_ARBLostBitEnum       CAN_PELI_GetArbitrationLostBit(void);
uint32_t                      CAN_PELI_GetErrorCodeCaptureReg(void);
CAN_PELI_ErrTypeEnum          CAN_PELI_ParseErrorType(uint32_t ErrorCode);
CAN_PELI_ErrDirectionEnum     CAN_PELI_ParseErrorDirection(uint32_t ErrorCode);
CAN_PELI_ErrSegmentEnum       CAN_PELI_ParseErrorSegment(uint32_t ErrorCode);
uint8_t                       CAN_PELI_GetReceiveMessageCounter(void);
uint8_t                       CAN_PELI_GetReceiveErrorCounter(void);
uint8_t                       CAN_PELI_GetTransmitErrorCounter(void);
void                          CAN_PELI_SetReceiveErrorCounter(uint8_t ErrorCnt);
void                          CAN_PELI_SetTransmitErrorCounter(uint8_t ErrorCnt);

void                          CAN_PELI_IntCmd(uint32_t CAN_PELI_IntType, FunctionalState Newstate);
FunctionalState               CAN_PELI_GetIntCmdStatus(uint32_t CAN_PELI_IntType);
FlagState                     CAN_PELI_GetIntFlagStatus(uint32_t CAN_PELI_IntFlag);
FlagState                     CAN_PELI_GetFlagStatus(uint32_t CAN_PELI_Flag);


#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

#ifdef __cplusplus
}

#endif

#endif /* DPM32M08X*/

#endif /* __DPM32M0XX_CAN_H__ */
