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