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