1 /*!
2  * @file        apm32f0xx_can.h
3  *
4  * @brief       This file contains all the functions prototypes for the CAN firmware library
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
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 __APM32F0XX_CAN_H
28 #define __APM32F0XX_CAN_H
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /* Includes */
35 #include "apm32f0xx.h"
36 
37 /** @addtogroup APM32F0xx_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup CAN_Driver
42   @{
43 */
44 
45 /** @defgroup CAN_Macros Macros
46   @{
47 */
48 
49 /**@} end of group CAN_Macros */
50 
51 /** @defgroup CAN_Enumerations Enumerations
52   @{
53 */
54 
55 /**
56  * @brief   CAN operating mode
57  */
58 typedef enum
59 {
60     CAN_OPERATING_MODE_INIT   = ((uint8_t)00), /*!< Initialization mode */
61     CAN_OPERATING_MODE_NORMAL = ((uint8_t)01), /*!< Normal mode */
62     CAN_OPERATING_MODE_SLEEP  = ((uint8_t)02), /*!< sleep mode */
63 } CAN_OPERATING_MODE_T;
64 
65 /**
66  * @brief   CAN test mode
67  */
68 typedef enum
69 {
70     CAN_MODE_NORMAL          = ((uint8_t)00),  /*!< normal mode */
71     CAN_MODE_LOOPBACK        = ((uint8_t)01),  /*!< loopback mode */
72     CAN_MODE_SILENT          = ((uint8_t)02),  /*!< silent mode */
73     CAN_MODE_SILENT_LOOPBACK = ((uint8_t)03),  /*!< loopback combined with silent mode */
74 } CAN_MODE_T;
75 
76 /**
77  * @brief   CAN filter mode
78  */
79 typedef enum
80 {
81     CAN_FILTER_MODE_IDMASK  = ((uint8_t)00),   /*!< identifier/mask mode */
82     CAN_FILTER_MODE_IDLIST  = ((uint8_t)01),   /*!< identifier list mode */
83 } CAN_FILTER_MODE_T;
84 
85 /**
86  * @brief   CAN synchronisation jump width
87  */
88 typedef enum
89 {
90     CAN_SJW_1 = ((uint8_t)00),                 /*!< 1 time quantum */
91     CAN_SJW_2 = ((uint8_t)01),                 /*!< 2 time quantum */
92     CAN_SJW_3 = ((uint8_t)02),                 /*!< 3 time quantum */
93     CAN_SJW_4 = ((uint8_t)03),                 /*!< 4 time quantum */
94 } CAN_SJW_T;
95 
96 /**
97  * @brief   CAN_time quantum in bit_segment_1
98  */
99 typedef enum
100 {
101     CAN_TIME_SEGMENT1_1  = (uint8_t)0x00,      /*!< 1  time quanta */
102     CAN_TIME_SEGMENT1_2  = (uint8_t)0x01,      /*!< 2  time quanta */
103     CAN_TIME_SEGMENT1_3  = (uint8_t)0x02,      /*!< 3  time quanta */
104     CAN_TIME_SEGMENT1_4  = (uint8_t)0x03,      /*!< 4  time quanta */
105     CAN_TIME_SEGMENT1_5  = (uint8_t)0x04,      /*!< 5  time quanta */
106     CAN_TIME_SEGMENT1_6  = (uint8_t)0x05,      /*!< 6  time quanta */
107     CAN_TIME_SEGMENT1_7  = (uint8_t)0x06,      /*!< 7  time quanta */
108     CAN_TIME_SEGMENT1_8  = (uint8_t)0x07,      /*!< 8  time quanta */
109     CAN_TIME_SEGMENT1_9  = (uint8_t)0x08,      /*!< 9  time quanta */
110     CAN_TIME_SEGMENT1_10 = (uint8_t)0x09,      /*!< 10 time quanta */
111     CAN_TIME_SEGMENT1_11 = (uint8_t)0x0A,      /*!< 11 time quanta */
112     CAN_TIME_SEGMENT1_12 = (uint8_t)0x0B,      /*!< 12 time quanta */
113     CAN_TIME_SEGMENT1_13 = (uint8_t)0x0C,      /*!< 13 time quanta */
114     CAN_TIME_SEGMENT1_14 = (uint8_t)0x0D,      /*!< 14 time quanta */
115     CAN_TIME_SEGMENT1_15 = (uint8_t)0x0E,      /*!< 15 time quanta */
116     CAN_TIME_SEGMENT1_16 = (uint8_t)0x0F,      /*!< 16 time quanta */
117 } CAN_TIME_SEGMENT1_T;
118 
119 /**
120  * @brief   CAN_time_quantum_in_bit_segment_2
121  */
122 typedef enum
123 {
124     CAN_TIME_SEGMENT2_1 = (uint8_t)0x00,       /*!< 1  time quanta */
125     CAN_TIME_SEGMENT2_2 = (uint8_t)0x01,       /*!< 2  time quanta */
126     CAN_TIME_SEGMENT2_3 = (uint8_t)0x02,       /*!< 3  time quanta */
127     CAN_TIME_SEGMENT2_4 = (uint8_t)0x03,       /*!< 4  time quanta */
128     CAN_TIME_SEGMENT2_5 = (uint8_t)0x04,       /*!< 5  time quanta */
129     CAN_TIME_SEGMENT2_6 = (uint8_t)0x05,       /*!< 6  time quanta */
130     CAN_TIME_SEGMENT2_7 = (uint8_t)0x06,       /*!< 7  time quanta */
131     CAN_TIME_SEGMENT2_8 = (uint8_t)0x07,       /*!< 8  time quanta */
132 } CAN_TIME_SEGMENT2_T;
133 
134 /**
135  * @brief   CAN_filter_scale
136  */
137 typedef enum
138 {
139     CAN_FILTER_SCALE_16BIT = ((uint8_t)0x00),  /*!< Two 16-bit filters */
140     CAN_FILTER_SCALE_32BIT = ((uint8_t)0x01),  /*!< One 32-bit filter */
141 } CAN_FILTER_SCALE_T;
142 
143 /**
144  * @brief   CAN identifier type
145  */
146 typedef enum
147 {
148     CAN_TYPEID_STD = ((uint32_t)0x00000000),   /*!< Standard Id */
149     CAN_TYPEID_EXT = ((uint32_t)0x00000004),   /*!< Extended Id */
150 } CAN_TYPEID_T;
151 
152 /**
153  * @brief   CAN_remote_transmission_request
154  */
155 typedef enum
156 {
157     CAN_RTXR_DATA   = ((uint32_t)0x00000000),  /*!< Data frame */
158     CAN_RTXR_REMOTE = ((uint32_t)0x00000002),  /*!< Remote frame */
159 } CAN_RTXR_T;
160 
161 /**
162  * @brief   CAN_transmit_constants
163  */
164 typedef enum
165 {
166     CAN_TX_FAILED       = ((uint8_t)0x00),     /*!< CAN transmission failed */
167     CAN_TX_OK           = ((uint8_t)0x01),     /*!< CAN transmission succeeded */
168     CAN_TX_WAITING      = ((uint8_t)0x02),     /*!< CAN waiting for transmission */
169     CAN_TX_MAILBOX_FULL = ((uint8_t)0x04),     /*!< CAN cell did not provide */
170 } CAN_TX_T;
171 
172 /**
173  * @brief   CAN sleep constants
174  */
175 typedef enum
176 {
177     CAN_SLEEP_FAILED = ((uint8_t)0x00),        /*!< CAN did not enter the sleep mode */
178     CAN_SLEEP_OK     = ((uint8_t)0x01),        /*!< CAN entered the sleep mode */
179 } CAN_SLEEP_T;
180 
181 /**
182  * @brief   CAN wake up constants
183  */
184 typedef enum
185 {
186     CAN_WAKEUP_FAILED = ((uint8_t)0x00),       /*!< CAN did not leave the sleep mode */
187     CAN_WAKEUP_OK     = ((uint8_t)0x01),       /*!< CAN leaved the sleep mode */
188 } CAN_WUP_T;
189 
190 /**
191  * @brief   CAN receive FIFO
192  */
193 typedef enum
194 {
195     CAN_FIFO_0 = ((uint8_t)0x00),              /*!< CAN FIFO 0 used to receive */
196     CAN_FIFO_1 = ((uint8_t)0x01),              /*!< CAN FIFO 1 used to receive */
197 } CAN_FIFO_T;
198 
199 /**
200  * @brief   CAN_error_Code_constants
201  */
202 typedef enum
203 {
204     CAN_ERROR_CODE_NOERR           = ((uint8_t)0x00), /*!< No Error */
205     CAN_ERROR_CODE_STUFFERR        = ((uint8_t)0x10), /*!< Stuff Error */
206     CAN_ERROR_CODE_FORMERR         = ((uint8_t)0x20), /*!< Form Error */
207     CAN_ERROR_CODE_ACKERR          = ((uint8_t)0x30), /*!< Acknowledgment Error */
208     CAN_ERROR_CODE_BITRECESSIVEERR = ((uint8_t)0x40), /*!< Bit Recessive Error */
209     CAN_ERROR_CODE_BITDOMINANTERR  = ((uint8_t)0x50), /*!< Bit Dominant Error */
210     CAN_ERROR_CODE_CRCERR          = ((uint8_t)0x60), /*!< CRC Error */
211     CAN_ERROR_CODE_SOFTWARESETERR  = ((uint8_t)0x70), /*!< Software Set Error */
212 } CAN_ERROR_CODE_T;
213 
214 /**
215  * @brief   Flags
216  */
217 typedef enum
218 {
219     /* Error Flags */
220     CAN_FLAG_EWF = ((uint32_t)0x10F00001),   /*!< Error Warning Flag */
221     CAN_FLAG_EPF = ((uint32_t)0x10F00002),   /*!< Error Passive Flag */
222     CAN_FLAG_BOF = ((uint32_t)0x10F00004),   /*!< Bus-Off Flag */
223     CAN_FLAG_LEC = ((uint32_t)0x30F00070),   /*!< Last error code Flag */
224     /* Operating Mode Flags */
225     CAN_FLAG_WUP  = ((uint32_t)0x31000008),  /*!< Wake up Flag */
226     CAN_FLAG_SLAK = ((uint32_t)0x31000012),  /*!< Sleep acknowledge Flag */
227     /* Transmit Flags */
228     CAN_FLAG_RQCP0 = ((uint32_t)0x32000001), /*!< Request MailBox0 Flag */
229     CAN_FLAG_RQCP1 = ((uint32_t)0x32000100), /*!< Request MailBox1 Flag */
230     CAN_FLAG_RQCP2 = ((uint32_t)0x32010000), /*!< Request MailBox2 Flag */
231     /* Receive Flags */
232     CAN_FLAG_FMP0 = ((uint32_t)0x14000003),  /*!< FIFO 0 Message Pending Flag */
233     CAN_FLAG_FF0  = ((uint32_t)0x34000008),  /*!< FIFO 0 Full Flag */
234     CAN_FLAG_FOV0 = ((uint32_t)0x34000010),  /*!< FIFO 0 Overrun Flag */
235     CAN_FLAG_FMP1 = ((uint32_t)0x18000003),  /*!< FIFO 1 Message Pending Flag */
236     CAN_FLAG_FF1  = ((uint32_t)0x38000008),  /*!< FIFO 1 Full Flag */
237     CAN_FLAG_FOV1 = ((uint32_t)0x38000010),  /*!< FIFO 1 Overrun Flag */
238 } CAN_FLAG_T;
239 
240 /**
241  * @brief   CAN interrupts
242  */
243 typedef enum
244 {
245     CAN_INT_TXME  = BIT0,  /*!< Transmit mailbox empty Interrupt */
246     CAN_INT_F0MP  = BIT1,  /*!< FIFO 0 message pending Interrupt */
247     CAN_INT_F0FUL = BIT2,  /*!< FIFO 0 full Interrupt */
248     CAN_INT_F0OVR = BIT3,  /*!< FIFO 0 overrun Interrupt */
249     CAN_INT_F1MP  = BIT4,  /*!< FIFO 1 message pending Interrupt */
250     CAN_INT_F1FUL = BIT5,  /*!< FIFO 1 full Interrupt */
251     CAN_INT_F1OVR = BIT6,  /*!< FIFO 1 overrun Interrupt */
252     CAN_INT_EWIE  = BIT8,  /*!< Error warning Interrupt */
253     CAN_INT_EPIE  = BIT9,  /*!< Error passive Interrupt */
254     CAN_INT_BOIE  = BIT10, /*!< Bus-off Interrupt */
255     CAN_INT_LEC   = BIT11, /*!< Last error code Interrupt */
256     CAN_INT_ERR   = BIT15, /*!< Error Interrupt */
257     CAN_INT_WUP   = BIT16, /*!< Wake-up Interrupt */
258     CAN_INT_SLE   = BIT17, /*!< Sleep acknowledge Interrupt */
259 } CAN_INT_T;
260 
261 typedef enum
262 {
263     CAN_FILTER_NUMBER_0 = 0, /*!< Number 0 of filters */
264     CAN_FILTER_NUMBER_1,     /*!< Number 1 of filters */
265     CAN_FILTER_NUMBER_2,     /*!< Number 2 of filters */
266     CAN_FILTER_NUMBER_3,     /*!< Number 3 of filters */
267     CAN_FILTER_NUMBER_4,     /*!< Number 4 of filters */
268     CAN_FILTER_NUMBER_5,     /*!< Number 5 of filters */
269     CAN_FILTER_NUMBER_6,     /*!< Number 6 of filters */
270     CAN_FILTER_NUMBER_7,     /*!< Number 7 of filters */
271     CAN_FILTER_NUMBER_8,     /*!< Number 8 of filters */
272     CAN_FILTER_NUMBER_9,     /*!< Number 9 of filters */
273     CAN_FILTER_NUMBER_10,    /*!< Number 10 of filters */
274     CAN_FILTER_NUMBER_11,    /*!< Number 11 of filters */
275     CAN_FILTER_NUMBER_12,    /*!< Number 12 of filters */
276     CAN_FILTER_NUMBER_13,    /*!< Number 13 of filters */
277 } CAN_FILTER_NUMBER_T;
278 
279 typedef enum
280 {
281     CAN_MAILBOX_0 = ((uint8_t)0x00), /*!< Tx mailbox0 */
282     CAN_MAILBOX_1 = ((uint8_t)0x01), /*!< Tx mailbox1 */
283     CAN_MAILBOX_2 = ((uint8_t)0x02), /*!< Tx mailbox2 */
284 } CAN_MAILBOX_T;
285 
286 /**@} end of group CAN_Enumerations */
287 
288 /** @defgroup CAN_Structures Structures
289   @{
290 */
291 
292 /**
293  * @brief   CAN config structure definition
294  */
295 typedef struct
296 {
297     uint8_t      timeTrigComMode;     /*!< Enable or disable the time triggered communication mode */
298     uint8_t      autoBusOffManage;    /*!< Enable or disable the automatic bus-off management */
299     uint8_t      autoWakeUpMode;      /*!< Enable or disable the automatic wake-up mode */
300     uint8_t      nonAutoRetran;       /*!< Enable or disable the non-automatic retransmission mode */
301     uint8_t      rxFIFOLockMode;      /*!< Enable or disable the Receive FIFO Locked mode */
302     uint32_t     txFIFOPriority;      /*!< Enable or disable the transmit FIFO priority */
303     CAN_MODE_T   mode;                /*!< Specifies the CAN operating mode */
304     CAN_SJW_T    syncJumpWidth;       /*!< Specifies the maximum number of time quanta the CAN hardware
305                                          is allowed to lengthen or shorten a bit to perform resynchronization. */
306     CAN_TIME_SEGMENT1_T timeSegment1; /*!< Specifies the number of time quanta in Bit Segment 1 */
307     CAN_TIME_SEGMENT2_T timeSegment2; /*!< Specifies the number of time quanta in Bit Segment 2 */
308     uint16_t            prescaler;    /*!< Specifies the length of a time quantum. It can be 1 to 1024 */
309 } CAN_Config_T;
310 
311 /**
312  * @brief   CAN filter config structure definition
313  */
314 typedef struct
315 {
316     uint16_t            filterIdHigh;        /*!< Specifies the filter identification number. */
317     uint16_t            filterIdLow;         /*!< Specifies the filter identification number. */
318     uint16_t            filterMaskIdHigh;    /*!< Specifies the filter mask number or identification number. */
319     uint16_t            filterMaskIdLow;     /*!< Specifies the filter mask number or identification number. */
320     CAN_FIFO_T          filterFIFO;          /*!< Specifies the FIFO which will be assigned to the filter. */
321     CAN_FILTER_NUMBER_T filterNumber;        /*!< Specifies the filter which will be configured. It ranges from 0 to 13. */
322     CAN_FILTER_MODE_T   filterMode;          /*!< Specifies the filter mode to be configured. */
323     CAN_FILTER_SCALE_T  filterScale;         /*!< Specifies the filter scale. */
324     uint8_t             filterActivation;    /*!< Enable or disable the filter. */
325 } CAN_FilterConfig_T;
326 
327 /**
328  * @brief   CAN Tx message structure definition
329  */
330 typedef struct
331 {
332     uint32_t    stanID;         /*!< Specifies the standard identifier. */
333     uint32_t    extenID;        /*!< Specifies the extended identifier. */
334     CAN_TYPEID_T typeID;        /*!< Specifies the type of identifier for the message. */
335     CAN_RTXR_T  remoteTxReq;    /*!< Specifies the type of frame for the message. */
336     uint8_t     dataLengthCode; /*!< Specifies the length of the frame. It can be a value between 0 to 8. */
337     uint8_t     data[8];        /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */
338 } CAN_Tx_Message;
339 
340 /**
341  * @brief   CAN Rx message structure definition
342  */
343 typedef struct
344 {
345     uint32_t    stanID;             /*!< Specifies the standard identifier. */
346     uint32_t    extenID;            /*!< Specifies the extended identifier. */
347     CAN_TYPEID_T typeID;            /*!< Specifies the type of identifier for the message. */
348     CAN_RTXR_T  remoteTxReq;        /*!< Specifies the type of frame for the message. */
349     uint8_t     dataLengthCode;     /*!< Specifies the length of the frame. It can be a value between 0 to 8. */
350     uint8_t     data[8];            /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */
351     uint8_t     filterMatchIndex;   /*!< Specifies the index of the filter the message stored in the mailbox passes through. */
352 } CAN_Rx_Message;
353 
354 /**@} end of group CAN_Structures */
355 
356 /** @defgroup CAN_Variables Variables
357   @{
358 */
359 
360 /**@} end of group CAN_Variables */
361 
362 /** @defgroup CAN_Functions Functions
363   @{
364 */
365 
366 /* CAN reset and configuration */
367 void CAN_Reset(void);
368 uint8_t CAN_Config(CAN_Config_T* canConfig);
369 void CAN_ConfigFilter(CAN_FilterConfig_T* filterConfig);
370 void CAN_ConfigStructInit(CAN_Config_T* canConfig);
371 void CAN_StartBankSlave(uint8_t bankNumber);
372 void CAN_EnableDebugFreeze(void);
373 void CAN_DisableDebugFreeze(void);
374 void CAN_EnableTTComMode(void);
375 void CAN_DisableTTComMode(void);
376 
377 /* CAN frames transmission */
378 uint8_t CAN_TxMessage(CAN_Tx_Message* TxMessage);
379 uint8_t CAN_TxMessageStatus(CAN_MAILBOX_T TxMailbox);
380 void CAN_CancelTx(CAN_MAILBOX_T TxMailbox);
381 
382 /* CAN frames reception */
383 void CAN_RxMessage(uint8_t FIFONumber, CAN_Rx_Message* RxMessage);
384 void CAN_ReleaseFIFO(uint8_t FIFONumber);
385 uint8_t CAN_PendingMessage(uint8_t FIFONumber);
386 
387 /* CAN operation modes */
388 uint8_t CAN_OperatingMode(CAN_OPERATING_MODE_T operatingMode);
389 uint8_t CAN_SleepMode(void);
390 uint8_t CAN_WakeUpMode(void);
391 
392 /* CAN bus error management */
393 uint8_t CAN_ReadLastErrorCode(void);
394 uint8_t CAN_ReadRxErrorCounter(void);
395 uint8_t CAN_ReadLSBTxErrorCounter(void);
396 
397 /* CAN interrupt and flag */
398 void CAN_EnableInterrupt(uint32_t interrupt);
399 void CAN_DisableInterrupt(uint32_t interrupt);
400 uint8_t CAN_ReadStatusFlag(CAN_FLAG_T CAN_FLAG);
401 void CAN_ClearStatusFlag(CAN_FLAG_T flag);
402 uint8_t CAN_ReadIntFlag(CAN_INT_T interrupt);
403 void CAN_ClearIntFlag(uint32_t interrupt);
404 
405 #ifdef __cplusplus
406 }
407 #endif
408 
409 #endif /* __APM32F0XX_CAN_H */
410 
411 /**@} end of group CAN_Functions */
412 /**@} end of group CAN_Driver */
413 /**@} end of group APM32F0xx_StdPeriphDriver */
414