1 /*!
2  * @file        apm32f10x_can.h
3  *
4  * @brief       This file contains all the functions prototypes for the CAN firmware library
5  *
6  * @version     V1.0.4
7  *
8  * @date        2022-12-01
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Define to prevent recursive inclusion */
27 #ifndef __APM32F10X_CAN_H
28 #define __APM32F10X_CAN_H
29 
30 /* Includes */
31 #include "apm32f10x.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /** @addtogroup APM32F10x_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup CAN_Driver CAN Driver
42   @{
43 */
44 
45 /** @defgroup CAN_Enumerations Enumerations
46   @{
47 */
48 
49 /**
50  * @brief CAN mode
51  */
52 typedef enum
53 {
54     CAN_MODE_NORMAL          = ((uint8_t)0x00),  /*!< normal mode */
55     CAN_MODE_LOOPBACK        = ((uint8_t)0x01),  /*!< loopback mode */
56     CAN_MODE_SILENT          = ((uint8_t)0x02),  /*!< silent mode */
57     CAN_MODE_SILENT_LOOPBACK = ((uint8_t)0x03)   /*!< loopback combined with silent mode */
58 } CAN_MODE_T;
59 
60 /**
61  * @brief CAN synchronisation jump width
62  */
63 typedef enum
64 {
65     CAN_SJW_1 = ((uint8_t)0x00),  /*!< 1 time quantum */
66     CAN_SJW_2 = ((uint8_t)0x01),  /*!< 2 time quantum */
67     CAN_SJW_3 = ((uint8_t)0x02),  /*!< 3 time quantum */
68     CAN_SJW_4 = ((uint8_t)0x03)   /*!< 4 time quantum */
69 } CAN_SJW_T;
70 
71 /**
72  * @brief CAN time quantum in bit segment 1
73  */
74 typedef enum
75 {
76     CAN_TIME_SEGMENT1_1  = ((uint8_t)0x00),  /*!< 1  time quanta */
77     CAN_TIME_SEGMENT1_2  = ((uint8_t)0x01),  /*!< 2  time quanta */
78     CAN_TIME_SEGMENT1_3  = ((uint8_t)0x02),  /*!< 3  time quanta */
79     CAN_TIME_SEGMENT1_4  = ((uint8_t)0x03),  /*!< 4  time quanta */
80     CAN_TIME_SEGMENT1_5  = ((uint8_t)0x04),  /*!< 5  time quanta */
81     CAN_TIME_SEGMENT1_6  = ((uint8_t)0x05),  /*!< 6  time quanta */
82     CAN_TIME_SEGMENT1_7  = ((uint8_t)0x06),  /*!< 7  time quanta */
83     CAN_TIME_SEGMENT1_8  = ((uint8_t)0x07),  /*!< 8  time quanta */
84     CAN_TIME_SEGMENT1_9  = ((uint8_t)0x08),  /*!< 9  time quanta */
85     CAN_TIME_SEGMENT1_10 = ((uint8_t)0x09),  /*!< 10 time quanta */
86     CAN_TIME_SEGMENT1_11 = ((uint8_t)0x0A),  /*!< 11 time quanta */
87     CAN_TIME_SEGMENT1_12 = ((uint8_t)0x0B),  /*!< 12 time quanta */
88     CAN_TIME_SEGMENT1_13 = ((uint8_t)0x0C),  /*!< 13 time quanta */
89     CAN_TIME_SEGMENT1_14 = ((uint8_t)0x0D),  /*!< 14 time quanta */
90     CAN_TIME_SEGMENT1_15 = ((uint8_t)0x0E),  /*!< 15 time quanta */
91     CAN_TIME_SEGMENT1_16 = ((uint8_t)0x0F)   /*!< 16 time quanta */
92 } CAN_TIME_SEGMENT1_T;
93 
94 /**
95  * @brief CAN time quantum in bit segment 2
96  */
97 typedef enum
98 {
99     CAN_TIME_SEGMENT2_1 = (uint8_t)0x00,     /*!< 1  time quanta */
100     CAN_TIME_SEGMENT2_2 = (uint8_t)0x01,     /*!< 2  time quanta */
101     CAN_TIME_SEGMENT2_3 = (uint8_t)0x02,     /*!< 3  time quanta */
102     CAN_TIME_SEGMENT2_4 = (uint8_t)0x03,     /*!< 4  time quanta */
103     CAN_TIME_SEGMENT2_5 = (uint8_t)0x04,     /*!< 5  time quanta */
104     CAN_TIME_SEGMENT2_6 = (uint8_t)0x05,     /*!< 6  time quanta */
105     CAN_TIME_SEGMENT2_7 = (uint8_t)0x06,     /*!< 7  time quanta */
106     CAN_TIME_SEGMENT2_8 = (uint8_t)0x07      /*!< 8  time quanta */
107 } CAN_TIME_SEGMENT2_T;
108 
109 /**
110  * @brief CAN filter FIFO
111  */
112 typedef enum
113 {
114     CAN_FILTER_FIFO_0 = ((uint8_t)0x00),     /*!< filter FIFO 0 */
115     CAN_FILTER_FIFO_1 = ((uint8_t)0x01)      /*!< filter FIFO 1 */
116 } CAN_FILTER_FIFO_T;
117 
118 /**
119  * @brief CAN filter mode
120  */
121 typedef enum
122 {
123     CAN_FILTER_MODE_IDMASK = ((uint8_t)0x00),/*!< identifier/mask mode */
124     CAN_FILTER_MODE_IDLIST = ((uint8_t)0x01) /*!< identifier list mode */
125 } CAN_FILTER_MODE_T;
126 
127 /**
128  * @brief CAN filter scale
129  */
130 typedef enum
131 {
132     CAN_FILTER_SCALE_16BIT = ((uint8_t)0x00), /*!< Two 16-bit filters */
133     CAN_FILTER_SCALE_32BIT = ((uint8_t)0x01)  /*!< One 32-bit filter */
134 } CAN_FILTER_SCALE_T;
135 
136 /**
137  * @brief CAN identifier type
138  */
139 typedef enum
140 {
141     CAN_TYPEID_STD = ((uint32_t)0x00000000), /*!< Standard Id */
142     CAN_TYPEID_EXT = ((uint32_t)0x00000004)  /*!< Extended Id */
143 } CAN_TYPEID_T;
144 
145 /**
146  * @brief CAN_remote_transmission_request
147  */
148 typedef enum
149 {
150     CAN_RTXR_DATA   = ((uint32_t)0x00000000), /*!< Data frame */
151     CAN_RTXR_REMOTE = ((uint32_t)0x00000002)  /*!< Remote frame */
152 } CAN_RTXR_T;
153 
154 /**
155  * @brief Mailboxes definition
156  */
157 typedef enum
158 {
159     CAN_TX_MAILBIX_0 = ((uint8_t)0x00), /*!< Tx mailbox0 */
160     CAN_TX_MAILBIX_1 = ((uint8_t)0x01), /*!< Tx mailbox1 */
161     CAN_TX_MAILBIX_2 = ((uint8_t)0x02)  /*!< Tx mailbox2 */
162 } CAN_TX_MAILBIX_T;
163 
164 /**
165  * @brief CAN receive FIFO number constants
166  */
167 typedef enum
168 {
169     CAN_RX_FIFO_0 = ((uint8_t)0x00), /*!< receive FIFO 0 */
170     CAN_RX_FIFO_1 = ((uint8_t)0x01)  /*!< receive FIFO 1 */
171 } CAN_RX_FIFO_T;
172 
173 /**
174  * @brief CAN Operating Mode
175  */
176 typedef enum
177 {
178     CAN_OPERATING_MODE_INIT   = ((uint8_t)0x00), /*!< Initialization mode */
179     CAN_OPERATING_MODE_NORMAL = ((uint8_t)0x01), /*!< Normal mode */
180     CAN_OPERATING_MODE_SLEEP  = ((uint8_t)0x02)  /*!< sleep mode */
181 } CAN_OPERATING_MODE_T;
182 
183 /**
184  * @brief CAN Interrupts
185  */
186 typedef enum
187 {
188     CAN_INT_TXME   = ((uint32_t)0x00000001), /*!< Transmit mailbox empty Interrupt */
189     CAN_INT_F0MP   = ((uint32_t)0x00000002), /*!< FIFO 0 message pending Interrupt */
190     CAN_INT_F0FULL = ((uint32_t)0x00000004), /*!< FIFO 0 full Interrupt */
191     CAN_INT_F0OVR  = ((uint32_t)0x00000008), /*!< FIFO 0 overrun Interrupt */
192     CAN_INT_F1MP   = ((uint32_t)0x00000010), /*!< FIFO 1 message pending Interrupt */
193     CAN_INT_F1FULL = ((uint32_t)0x00000020), /*!< FIFO 1 full Interrupt */
194     CAN_INT_F1OVR  = ((uint32_t)0x00000040), /*!< FIFO 1 overrun Interrupt */
195     CAN_INT_ERRW   = ((uint32_t)0x00000100), /*!< Error warning Interrupt */
196     CAN_INT_ERRP   = ((uint32_t)0x00000200), /*!< Error passive Interrupt */
197     CAN_INT_BOF    = ((uint32_t)0x00000400), /*!< Bus-off Interrupt */
198     CAN_INT_LEC    = ((uint32_t)0x00000800), /*!< Last error record code Interrupt */
199     CAN_INT_ERR    = ((uint32_t)0x00008000), /*!< Error Interrupt */
200     CAN_INT_WUP    = ((uint32_t)0x00010000), /*!< Wake-up Interrupt */
201     CAN_INT_SLEEP  = ((uint32_t)0x00020000)  /*!< Sleep acknowledge Interrupt */
202 } CAN_INT_T;
203 
204 /**
205  * @brief CAN Flags
206  */
207 typedef enum
208 {
209     /** Error flag*/
210     CAN_FLAG_ERRW   = ((uint32_t)0x10F00001),  /*!< Error Warning Flag */
211     CAN_FLAG_ERRP   = ((uint32_t)0x10F00002),  /*!< Error Passive Flag */
212     CAN_FLAG_BOF    = ((uint32_t)0x10F00004),  /*!< Bus-Off Flag */
213     CAN_FLAG_LERRC  = ((uint32_t)0x30F00070),  /*!< Last error record code Flag */
214     /** Operating Mode Flags */
215     CAN_FLAG_WUPI   = ((uint32_t)0x31000008),  /*!< Wake up Flag */
216     CAN_FLAG_SLEEP  = ((uint32_t)0x31000012),  /*!< Sleep acknowledge Flag */
217     /** Receive Flags */
218     CAN_FLAG_F0MP   = ((uint32_t)0x12000003),  /*!< FIFO 0 Message Pending Flag */
219     CAN_FLAG_F0FULL = ((uint32_t)0x32000008),  /*!< FIFO 0 Full Flag */
220     CAN_FLAG_F0OVR  = ((uint32_t)0x32000010),  /*!< FIFO 0 Overrun Flag */
221     CAN_FLAG_F1MP   = ((uint32_t)0x14000003),  /*!< FIFO 1 Message Pending Flag */
222     CAN_FLAG_F1FULL = ((uint32_t)0x34000008),  /*!< FIFO 1 Full Flag */
223     CAN_FLAG_F1OVR  = ((uint32_t)0x34000010),  /*!< FIFO 1 Overrun Flag */
224     /** Transmit Flags */
225     CAN_FLAG_REQC0  = ((uint32_t)0x38000001),  /*!< Request MailBox0 Flag */
226     CAN_FLAG_REQC1  = ((uint32_t)0x38000100),  /*!< Request MailBox1 Flag */
227     CAN_FLAG_REQC2  = ((uint32_t)0x38010000)   /*!< Request MailBox2 Flag */
228 } CAN_FLAG_T;
229 
230 /**@} end of group CAN_Enumerations*/
231 
232 /** @defgroup CAN_Structures Structures
233   @{
234 */
235 
236 /**
237  * @brief    CAN Config structure definition
238  */
239 
240 /**
241  * @brief CAN config structure definition
242  */
243 typedef struct
244 {
245     uint8_t      autoBusOffManage;    /*!< Enable or disable the automatic bus-off management. */
246     uint8_t      autoWakeUpMode;      /*!< Enable or disable the automatic wake-up mode. */
247     uint8_t      nonAutoRetran;       /*!< Enable or disable the non-automatic retransmission mode. */
248     uint8_t      rxFIFOLockMode;      /*!< Enable or disable the Receive FIFO Locked mode. */
249     uint8_t      txFIFOPriority;      /*!< Enable or disable the transmit FIFO priority. */
250     CAN_MODE_T   mode;                /*!< Specifies the CAN operating mode. */
251     CAN_SJW_T    syncJumpWidth;       /* Specifies the maximum number of time quanta the CAN hardware
252                                          is allowed to lengthen or shorten a bit to perform resynchronization.
253                                       */
254     CAN_TIME_SEGMENT1_T timeSegment1; /*!< Specifies the number of time quanta in Bit Segment 1. */
255     CAN_TIME_SEGMENT2_T timeSegment2; /*!< Specifies the number of time quanta in Bit Segment 2. */
256     uint16_t            prescaler;    /*!< Specifies the length of a time quantum. It can be 1 to 1024. */
257 } CAN_Config_T;
258 
259 /**
260  * @brief  CAN Tx message structure definition
261  */
262 typedef struct
263 {
264     uint32_t            stdID;         /*!< Specifies the standard identifier. It can be 0 to 0x7FF. */
265     uint32_t            extID;         /*!< Specifies the extended identifier. It can be 0 to 0x1FFFFFFF. */
266     CAN_TYPEID_T        typeID;
267     CAN_RTXR_T          remoteTxReq;
268     uint8_t             dataLengthCode;/*!< Specifies the data length code.       It can be 0 to 8. */
269     uint8_t             data[8];       /*!< Specifies the data to be transmitted. It can be 0 to 0xFF. */
270 } CAN_TxMessage_T;
271 
272 /**
273  * @brief  CAN Rx message structure definition
274  */
275 typedef struct
276 {
277     uint32_t            stdID;           /*!< Specifies the standard identifier. It can be 0 to 0x7FF. */
278     uint32_t            extID;           /*!< Specifies the extended identifier. It can be 0 to 0x1FFFFFFF. */
279     uint32_t            typeID;
280     uint32_t            remoteTxReq;
281     uint8_t             dataLengthCode;  /*!< Specifies the data length code.       It can be 0 to 8. */
282     uint8_t             data[8];         /*!< Specifies the data to be transmitted. It can be 0 to 0xFF. */
283     uint8_t             filterMatchIndex;/*!< Specifies the filter match index.     It can be 0 to 0xFF. */
284 } CAN_RxMessage_T;
285 
286 /**
287  * @brief     CAN filter config structure definition
288  */
289 typedef struct
290 {
291     uint8_t             filterNumber;      /*!< Specifies the filter number. It can be 0 to 13. */
292     uint16_t            filterIdHigh;      /*!< Specifies the filter identification number.It can be 0 to 0xFFFF. */
293     uint16_t            filterIdLow;       /*!< Specifies the filter identification number.It can be 0 to 0xFFFF. */
294     uint16_t            filterMaskIdHigh;  /*!< Specifies the filter mask identification.  It can be 0 to 0xFFFF. */
295     uint16_t            filterMaskIdLow;   /*!< Specifies the filter mask identification.  It can be 0 to 0xFFFF. */
296     uint16_t            filterActivation;  /*!< Specifies the filter Activation. It can be ENABLE or DISABLE. */
297     CAN_FILTER_FIFO_T   filterFIFO;
298     CAN_FILTER_MODE_T   filterMode;
299     CAN_FILTER_SCALE_T  filterScale;
300 } CAN_FilterConfig_T;
301 
302 /**@} end of group CAN_Structures*/
303 
304 
305 /** @defgroup CAN_Functions Functions
306   @{
307 */
308 
309 /* CAN reset and configuration */
310 void CAN_Reset(CAN_T* can);
311 uint8_t CAN_Config(CAN_T* can, CAN_Config_T* canConfig);
312 #if defined(APM32F10X_CL)
313 void CAN_ConfigFilter(CAN_FilterConfig_T* filterConfig);
314 void CAN_SlaveStartBank(uint8_t bankNum);
315 #else
316 void CAN_ConfigFilter(CAN_T* can, CAN_FilterConfig_T* filterConfig);
317 #endif
318 void CAN_ConfigStructInit(CAN_Config_T* canConfig);
319 void CAN_EnableDBGFreeze(CAN_T* can);
320 void CAN_DisableDBGFreeze(CAN_T* can);
321 
322 /* CAN frames transmit */
323 uint8_t CAN_TxMessage(CAN_T* can, CAN_TxMessage_T* TxMessage);
324 uint8_t CAN_TxMessageStatus(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox);
325 void CAN_CancelTxMailbox(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox);
326 
327 /* CAN frames receive */
328 void CAN_RxMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber, CAN_RxMessage_T* RxMessage);
329 void CAN_ReleaseFIFO(CAN_T* can, CAN_RX_FIFO_T FIFONumber);
330 uint8_t CAN_PendingMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber);
331 
332 /* CAN operation modes */
333 uint8_t CAN_OperatingMode(CAN_T* can, CAN_OPERATING_MODE_T operatingMode);
334 uint8_t CAN_SleepMode(CAN_T* can);
335 uint8_t CAN_WakeUpMode(CAN_T* can);
336 
337 /* CAN bus error management */
338 uint8_t CAN_ReadLastErrorCode(CAN_T* can);
339 uint8_t CAN_ReadRxErrorCounter(CAN_T* can);
340 uint8_t CAN_ReadLSBTxErrorCounter(CAN_T* can);
341 
342 /* CAN interrupt and flag */
343 void CAN_EnableInterrupt(CAN_T* can, uint32_t interrupt);
344 void CAN_DisableInterrupt(CAN_T* can, uint32_t interrupt);
345 uint8_t CAN_ReadStatusFlag(CAN_T* can, CAN_FLAG_T flag);
346 void CAN_ClearStatusFlag(CAN_T* can, CAN_FLAG_T flag);
347 uint8_t CAN_ReadIntFlag(CAN_T* can, CAN_INT_T flag);
348 void CAN_ClearIntFlag(CAN_T* can, CAN_INT_T flag);
349 
350 /**@} end of group CAN_Functions*/
351 /**@} end of group CAN_Driver */
352 /**@} end of group APM32F10x_StdPeriphDriver */
353 
354 #ifdef __cplusplus
355 }
356 #endif
357 
358 #endif /* __APM32F10X_CAN_H */
359