/**
  ******************************************************************************
             Copyright(c) 2021 China Core Co. Ltd.
                      All Rights Reserved
  ******************************************************************************
  * @file    can_drv.h
  * @author  Product application department
  * @version V1.0
  * @date    2021.06.07
  * @brief   Header file of CAN DRV module..
  ******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_DRV_H
#define __CAN_DRV_H

#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "drv_reg.h"
#include "drv_gpio_def.h"
#include "ioctrl_drv.h"

#ifdef FILE_OUT
/**@defgroup DRV 3 HAL driver
  *
  *@{
  */

/** @defgroup DRV_CAN CAN
  *
  *@{
  */
#endif

/*** 宏定义 *******************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_UART_Exported_Macros Exported Macros
  *
  * @{
  */
#endif
/**
  * @brief  CAN 常用宏常量
  *
  */

#define CAN_BUFFER_NUM  64
#define CAN_RXIMR_ADDR_OFFSET 0x880
#define CAN_FIFO_ID_TABLE_ADDR_OFFSET 0x0E0

/*CAN 宏函数功能定义*/
/*MCR register*/
#define _can_en_module_disable_mode(can)         _bit_set(can->CAN_MCR,CAN_MCR_MDIS)
#define _can_dis_module_disable_mode(can)        _bit_clr(can->CAN_MCR,CAN_MCR_MDIS)
#define _can_en_generate_wrn_int_flag(can)       _bit_set(can->CAN_MCR,CAN_MCR_WRN_EN)
#define _can_dis_generate_wrn_int_flag(can)      _bit_clr(can->CAN_MCR,CAN_MCR_WRN_EN)
#define _can_en_soft_rst(can)                    _bit_set(can->CAN_MCR,CAN_MCR_SOFT_RST)  
#define _can_en_support_previous_versions(can)   _bit_set(can->CAN_MCR,CAN_MCR_BCC)
#define _can_dis_support_previous_versions(can)  _bit_clr(can->CAN_MCR,CAN_MCR_BCC)
#define _can_en_all_message_buffers(can)         _bit_set(can->CAN_MCR,CAN_MCR_MAXMB)             
#define _can_en_fifo(can)                        _bit_set(can->CAN_MCR,CAN_MCR_FEN)  
#define _can_dis_fifo(can)                       _bit_clr(can->CAN_MCR,CAN_MCR_FEN)
#define _can_exit_freeze_mode(can)               _bit_clr(can->CAN_MCR,(CAN_MCR_HALT | CAN_MCR_FRZ))
#define _can_enter_freeze_mode(can)              _bit_set(can->CAN_MCR,(CAN_MCR_HALT | CAN_MCR_FRZ))

/*CR register*/
#define _can_select_peripheral_clock(can)           _bit_set(can->CAN_CR,CAN_CR_CLK_SRC)
#define _can_select_crystal_oscillator_clock(can)   _bit_clr(can->CAN_CR,CAN_CR_CLK_SRC)
#define _can_select_loop_back_mode(can)             _bit_set(can->CAN_CR,CAN_CR_LPB)   
#define _can_select_normal_mode(can)                _bit_clr(can->CAN_CR,CAN_CR_LPB) 
#define _can_en_listen_only_mode(can)               _bit_set(can->CAN_CR,CAN_CR_LOM)
#define _can_dis_listen_only_mode(can)              _bit_clr(can->CAN_CR,CAN_CR_LOM)
#define _can_lowest_buf_num_first(can)              _bit_set(can->CAN_CR,CAN_CR_LBUF)
#define _can_lowest_id_num_first(can)               _bit_clr(can->CAN_CR,CAN_CR_LBUF)

/*SR register*/
#define _can_get_esr_val(can)                       _reg_read(can->CAN_ESR)
#define _can_get_buss_off_int_flag(can)             _reg_chk(can->CAN_ESR, CAN_ESR_BOFF_INT)
#define _can_clr_buss_off_int_flag(can)             _bit_set(can->CAN_ESR, CAN_ESR_BOFF_INT)
#define _can_get_twrn_int_flag(can)                 _reg_chk(can->CAN_ESR, CAN_ESR_TWRN_INT)
#define _can_clr_twrn_int_flag(can)                 _bit_set(can->CAN_ESR, CAN_ESR_TWRN_INT)
#define _can_get_rwrn_int_flag(can)                 _reg_chk(can->CAN_ESR, CAN_ESR_RWRN_INT)
#define _can_clr_rwrn_int_flag(can)                 _bit_set(can->CAN_ESR, CAN_ESR_RWRN_INT)
#define _can_get_err_int_flag(can)                  _reg_chk(can->CAN_ESR, CAN_ESR_ERR_INT)
#define _can_clr_err_int_flag(can)                  _bit_set(can->CAN_ESR, CAN_ESR_ERR_INT)

/*FRT register*/
#define _can_set_free_time(can,val)                 _reg_write(can->CAN_FRT,val);
#define _can_get_free_time(can)                     _reg_read(can->CAN_FRT);

/*IMASK register*/
#define _can_en_mb0_31_int(can)                     _reg_write(can->CAN_IM1R, 0xffffffff)
#define _can_en_mb32_63_int(can)                    _reg_write(can->CAN_IM2R, 0xffffffff)
#define _can_dis_mb0_31_int(can)                    _reg_write(can->CAN_IM1R, 0)
#define _can_dis_mb32_63_int(can)                   _reg_write(can->CAN_IM2R, 0)

/*IFR register*/
#define _can_get_mb0_31_int_flag(can)               _reg_read(can->CAN_IF1R)
#define _can_get_mb32_63_int_flag(can)              _reg_read(can->CAN_IF2R)
#define _can_clr_mb0_31_int_flag(can,val)           _bit_set(can->CAN_IF1R,val)
#define _can_clr_mb32_63_int_flag(can,val)          _bit_set(can->CAN_IF2R,val)

/**
  * @}
  */

/*** 结构体、枚举变量定义 *****************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_CAN_Exported_Types Exported Types
  *
  * @{
  */
#endif


/**
  * @brief CAN_Identifier_Type CAN Identifier Type
  */
typedef enum
{
    DRV_CAN_ID_STD   = 0x00000000U,   /*!< Standard Id */
    DRV_CAN_ID_EXT   = 0x00200000U,   /*!< Extended Id */
}DRV_CAN_IDETypeDef;


/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
  * @{
  */
typedef enum
{
    DRV_CAN_RTR_DATA     = 0x00000000U,   /*!< Data frame */
    DRV_CAN_RTR_REMOTE   = 0x00100000U,   /*!< Remote frame  */
}DRV_CAN_RTRTypeDef;

/**
  * @brief  CAN Tx message structure definition
  */
typedef struct
{
    uint32_t StdId;              /*!< Specifies the standard identifier.
                                    This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
    uint32_t ExtId;              /*!< Specifies the extended identifier.
                                    This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
    DRV_CAN_IDETypeDef IDE;      /*!< Specifies the type of identifier for the message that will be transmitted.
                                    This parameter can be a value of @ref CAN_Identifier_Type */
    DRV_CAN_RTRTypeDef RTR;      /*!< Specifies the type of frame for the message that will be transmitted.
                                    This parameter can be a value of @ref CAN_remote_transmission_request */
    uint32_t DLC;                /*!< Specifies the length of the frame that will be transmitted.
                                    This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
    uint8_t Data[8];             /*!< Contains the data to be transmitted.
                                    This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
}CanTxMsgTypeDef;

/**
  * @brief  CAN Rx message structure definition
  */
typedef struct
{
    uint32_t StdId;                 /*!< Specifies the standard identifier.
                                         This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
    uint32_t ExtId;                 /*!< Specifies the extended identifier.
                                         This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
    DRV_CAN_IDETypeDef IDE;         /*!< Specifies the type of identifier for the message that will be received.
                                         This parameter can be a value of @ref CAN_Identifier_Type */
    DRV_CAN_RTRTypeDef RTR;         /*!< Specifies the type of frame for the received message.
                                         This parameter can be a value of @ref CAN_remote_transmission_request */
    uint32_t DLC;                   /*!< Specifies the length of the frame that will be received.
                                         This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
    uint8_t Data[8];                /*!< Contains the data to be received.
                                         This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
    uint32_t RXIM;                  /*!< Specifies the RX individual mask. */
    
    uint32_t MBID;                  /*!< Specifies the MB number.
                                         This parameter can be 0 to 32*/
}CanRxMsgTypeDef;

#define CAN_RX_MAX_LEN  	8
typedef struct 
{
	u16 rp;//read pointer
	u16 wp;//write pointer
	u8  dat[CAN_RX_MAX_LEN];//buffer
}CanRxBufStruct;

/**
  * @brief CAN状态
  */
typedef enum
{
    DRV_CAN_OK       = 0x00,
    DRV_CAN_ERROR    = 0x01,
    DRV_CAN_BUSY     = 0x02,
    DRV_CAN_TIMEOUT  = 0x03,
}DRV_CAN_StatusTypeDef;

/**
  * @brief UART 初始化结构体定义
  */
typedef struct
{
    uint32_t BitRate;    /**< CAN模块配置的位速率 */
    uint32_t FEN;        /**< Enable or disable the FIFO .
                              This parameter can be set to ENABLE or DISABLE */
    uint32_t IPSFreq;    /**< CAN模块时钟频率 */
	  uint32_t TransmitInterrupt; /**< CAN发送是否产生中断*/
	  uint32_t ReceiveInterrupt; /**< CAN接收是否产生中断 */
    
} CAN_InitTypeDef,*pCAN_InitTypeDef;

/**
  * @brief structure used to configure CAN bitrate
  */
typedef struct
{
	uint8_t m_propseg;			    // CAN control register propseg area
	uint8_t m_pseg1;				// CAN control register pseg1 area
	uint8_t m_pseg2;				// CAN control register pseg2 area
}can_timeseg;

/**
  * @}
  */

/*** 全局变量声明 **************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_UART_Exported_Variables Exported Variables
  *
  * @{
  */
#endif


/**
  * @}
  */

/*** 函数声明 ******************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_UART_Exported_Functions Exported Functions
  * @{
  */
#endif

extern volatile UINT32 gCanErrFlag;
extern volatile UINT32 gCanIFlag1;
extern volatile UINT32 gCanIFlag2;
extern volatile UINT32 gCanFifoEnable;
extern volatile CanRxMsgTypeDef gCanRxmsg[];
extern volatile UINT32 gCanFifoRxLen;

extern u8 canDataBuf[];
extern CanRxBufStruct gCantRx;
extern volatile CanRxMsgTypeDef gCantRxMsg;


extern void DRV_CAN0_3_Handler(void);
extern void DRV_CAN4_7_Handler(void);
extern void DRV_CAN8_11_Handler(void);
extern void DRV_CAN12_15_Handler(void);
extern void DRV_CAN16_31_Handler(void);
extern void DRV_CAN32_63_Handler(void);


extern DRV_CAN_StatusTypeDef DRV_CAN_Init(CAN_TypeDef *pcan, CAN_InitTypeDef *Init);
extern void DRV_CAN_DeInit(CAN_TypeDef *pcan);
extern DRV_CAN_StatusTypeDef DRV_CAN_TransmitBytes(CAN_TypeDef *pcan, CanTxMsgTypeDef *pTxmsg, uint32_t Timeout);
extern DRV_CAN_StatusTypeDef DRV_CAN_ReceiveBytes(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg, uint32_t rx_num, uint32_t Timeout);
extern DRV_CAN_StatusTypeDef DRV_CAN_FIFO_ReceiveBytes(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg,uint32_t rx_num ,uint32_t Timeout);

extern DRV_CAN_StatusTypeDef DRV_CAN_TransmitBytesIT(CAN_TypeDef *pcan, CanTxMsgTypeDef *pTxmsg, uint32_t Timeout);
extern DRV_CAN_StatusTypeDef DRV_CAN_ReceiveBytesIT(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg, uint32_t rx_num, uint32_t Timeout);
extern DRV_CAN_StatusTypeDef DRV_CAN_FIFO_ReceiveBytesIT(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg,uint32_t rx_num ,uint32_t Timeout);







extern CanRxBufStruct gCantRx;

extern u8 CanRecieved(void);
extern u8 CanRecvByte(UINT8 *dat);

/**
  * @}
  */

/**
  *@}
  */

/**
  *@}
  */

#ifdef __cplusplus
}

#endif  
#endif /* __CAN_DRV_H */
/************************ (C) COPYRIGHT C*Core *****END OF FILE**********************/
