1 /**
2     *****************************************************************************
3     * @file     cmem7_can.h
4     *
5     * @brief    CMEM7 CAN header file
6     *
7     *
8     * @version  V1.0
9     * @date     3. September 2013
10     *
11     * @note
12     *
13     *****************************************************************************
14     * @attention
15     *
16     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
17     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
18     * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
19     * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
20     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
21     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
22     *
23     * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
24     *****************************************************************************
25     */
26 
27 #ifndef __CMEM7_CAN_H
28 #define __CMEM7_CAN_H
29 
30 #ifdef __cplusplus
31  extern "C" {
32 #endif
33 
34 #include "cmem7.h"
35 #include "cmem7_conf.h"
36 
37 #define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN0) || \
38                                    ((PERIPH) == CAN1))
39 
40 /** @defgroup CAN_FLT
41   * @{
42   */
43 #define CAN_FLT_STANDARD_SINGLE    0x00000000
44 #define CAN_FLT_STANDARD_DUAL      0x00000001
45 #define CAN_FLT_EXTENDED_SINGLE    0x00000002
46 #define CAN_FLT_EXTENDED_DUAL      0x00000003
47 
48 #define IS_CAN_FLT_TYPE(FILTER)    (((FILTER) == CAN_FLT_STANDARD_SINGLE) || \
49                                     ((FILTER) == CAN_FLT_STANDARD_DUAL) || \
50                                                                         ((FILTER) == CAN_FLT_EXTENDED_SINGLE) || \
51                                     ((FILTER) == CAN_FLT_EXTENDED_DUAL))
52 
53 #define IS_CAN_FLT_SINGLE(FILTER)  (((FILTER) == CAN_FLT_STANDARD_SINGLE) || \
54                                     ((FILTER) == CAN_FLT_EXTENDED_SINGLE))
55 
56 #define IS_CAN_FLT_DUAL(FILTER)    (IS_CAN_FLT_TYPE(FILTER) && \
57                                     !IS_CAN_FLT_SINGLE(FILTER))
58 
59 /**
60   * @}
61   */
62 
63 /** @defgroup CAN_CDR_DIV
64   * @{
65   */
66 #define CAN_CDR_DIV_1_2            0x0
67 #define CAN_CDR_DIV_1_4            0x1
68 #define CAN_CDR_DIV_1_6            0x2
69 #define CAN_CDR_DIV_1_8            0x3
70 #define CAN_CDR_DIV_1_10           0x4
71 #define CAN_CDR_DIV_1_12           0x5
72 #define CAN_CDR_DIV_1_14           0x6
73 #define CAN_CDR_DIV_1_1            0x7
74 
75 #define IS_CAN_CDR_DIV(DIV)        (((DIV) == CAN_CDR_DIV_1_2) || \
76                                     ((DIV) == CAN_CDR_DIV_1_4) || \
77                                                                         ((DIV) == CAN_CDR_DIV_1_6) || \
78                                                                         ((DIV) == CAN_CDR_DIV_1_8) || \
79                                                                         ((DIV) == CAN_CDR_DIV_1_10) || \
80                                                                         ((DIV) == CAN_CDR_DIV_1_12) || \
81                                                                         ((DIV) == CAN_CDR_DIV_1_14) || \
82                                                                         ((DIV) == CAN_CDR_DIV_1_1))
83 /**
84   * @}
85   */
86 
87 /** @defgroup CAN_INT
88   * @{
89   */
90 #define CAN_INT_RBNF               0x01
91 #define CAN_INT_TB_UNLOCK          0x02
92 #define CAN_INT_ERR                0x04
93 #define CAN_INT_DATA_OVERRUN       0x08
94 #define CAN_INT_WAKEUP             0x10
95 #define CAN_INT_ERR_PASSIVE        0x20
96 #define CAN_INT_ARBITRATION_LOST   0x40
97 #define CAN_INT_BUS_ERR            0x80
98 #define CAN_INT_All                0xFF
99 
100 #define IS_CAN_INT(INT)            (((INT) != 0) && (((INT) & ~CAN_INT_All) == 0))
101 /**
102   * @}
103   */
104 
105 /**
106   * @brief  CAN standard filter structure
107     */
108 typedef struct {
109     uint16_t  ID28_18;               /*!< 11 bits                                      */
110   BOOL      RTR;                   /*!< if remote frame                              */
111     uint8_t   data1;                 /*!< data byte 1, if not 2nd CAN_FLT_STANDARD_DUAL*/
112     uint8_t   data2;                 /*!< data byte 2, if CAN_FLT_STANDARD_SINGLE      */
113 } CAN_STANDARD_FILTER;
114 
115 /**
116   * @brief  CAN extended filter structure
117     */
118 typedef struct {
119     uint16_t  ID28_13;               /*!< 16 bits                                      */
120     uint16_t  ID12_0;                /*!< 13 bits, if CAN_FLT_EXTENDED_SINGLE          */
121   BOOL      RTR;                   /*!< if remote frame, if CAN_FLT_EXTENDED_SINGLE  */
122 } CAN_EXTENDED_FILTER;
123 
124 /**
125   * @brief  CAN filter structure
126     */
127 typedef struct {
128     uint8_t   type;                  /*!< Filter type, which is a value of @ref CAN_FLT */
129 
130     /**
131   * @brief  accepted filter
132     */
133     union {
134         CAN_STANDARD_FILTER sf;
135         CAN_EXTENDED_FILTER ef;
136     } ACCEPT;
137 
138     /**
139   * @brief  filter mask
140     */
141     union {
142         CAN_STANDARD_FILTER sf;
143         CAN_EXTENDED_FILTER ef;
144     } MASK;
145 } CAN_FILTER;
146 
147 /**
148   * @brief  CAN initialization structure
149     */
150 typedef struct {
151     BOOL CAN_TxEn;                       /*!< if transmission is enable                                         */
152     BOOL CAN_Loopback;                   /*!< loop back mode without phy                                        */
153   uint8_t CAN_ClockDiv;                  /*!< input clock divider, ref as @ref CAN_CDR_DIV  */
154     uint16_t CAN_Prescaler;              /*!< Specifies the length of a time quantum.
155                                                                                 Time quantum = (CAN_Prescaler + 1) * 2 * input clock */
156   uint8_t CAN_SJW;                       /*!< Specifies the maximum number of time quanta
157                                                                                 the CAN hardware is allowed to lengthen or
158                                                                                 shorten a bit to perform resynchronization.     */
159     uint8_t CAN_TSEG1;                   /*!< the maximum number of time quanta of
160                                                                                 propagation and 1st phase segment                       */
161   uint8_t CAN_TSEG2;                     /*!< the maximum number of time quanta of 2nd
162                                                                                 phase segment                                                                   */
163   BOOL CAN_HighSpeed;                    /*!< if CAN is running on high speed bus (class C) */
164 } CAN_InitTypeDef;
165 
166 /**
167   * @brief  CAN frame structure
168     */
169 typedef struct
170 {
171   BOOL SFF;                                      /*!< If standard or extended frame format                  */
172     uint32_t Id;                                     /*!< Specifies the identifier.This parameter can
173                                                                                 be a value between 0 to 0x1FFFFFFF.                     */
174   BOOL RTR;                                      /*!< Specifies if the frame is a remote frame      */
175   uint8_t DLC;                                   /*!< Specifies the length of the frame, which is
176                                                                                 a value between  0 to 8                                             */
177   uint8_t Data[8];                               /*!< Frame data                                                                        */
178 } CAN_Frame;
179 
180 /**
181   * @brief  CAN initialization
182   * @note   This function should be called at first before any other interfaces.
183     * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
184     * @param[in] Init A pointer to structure CAN_InitTypeDef
185     * @param[in] f1 A pointer to structure CAN_FILTER
186     * @param[in] f2 NULL if single filter, or a pointer to second filter while dual filters
187   * @retval BOOL The bit indicates if specific CAN is initialized or not
188     */
189 BOOL CAN_Init(CAN0_Type* CANx, CAN_InitTypeDef* Init,
190   CAN_FILTER *f1, CAN_FILTER *f2);
191 
192 /**
193   * @brief  CAN is set to sleep or wake up
194   * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
195     * @param[in] Enable The bit indicates if sleep mode is enable or not
196     * @retval None
197     */
198 void CAN_SetSleepMode(CAN0_Type* CANx, BOOL enable);
199 
200 /**
201   * @brief  Enable or disable UART interrupt.
202     * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
203     * @param[in] Int interrupt mask bits, which can be the combination of @ref CAN_INT
204     * @param[in] Enable The bit indicates if specific interrupts are enable or not
205   * @retval None
206     */
207 void CAN_EnableInt(CAN0_Type* CANx, uint32_t Int, BOOL enable);
208 
209 /**
210   * @brief  Check specific interrupts are set or not
211     * @note   All interrupts except for receive int are cleared after call this func.
212     * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
213     * @retval uint8_t CAN interrupt bits, which can be the combination of @ref CAN_INT
214     */
215 uint8_t CAN_GetIntStatus(CAN0_Type* CANx);
216 
217 /**
218   * @brief  CAN perform to transmit data
219     * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
220     * @param[in] frame A pointer to the CAN_Frame to be transmitted
221     * @retval BOOL The bit indicates if data is transmitted or not
222     */
223 BOOL CAN_Transmit(CAN0_Type* CANx, CAN_Frame* frame);
224 
225 /**
226   * @brief  CAN perform to receive data
227     * @param[in] CANx CAN peripheral, which is CAN0 or CAN1
228     * @param[out] frame A user-allocated buffer to fetch received frame
229     * @retval BOOL The bit indicates if data is recieved or not
230     */
231 BOOL CAN_Receive(CAN0_Type* CANx, CAN_Frame* frame);
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif /* __CMEM7_CAN_H */
238